Topic: How about changing assgn of obj w/o vir dtor (Was Extending the string class)


Author: Waranun Bunjongsat <bunjonwa@trek.CS.ORST.EDU>
Date: 1999/08/24
Raw View
On Tue, 17 Aug 1999, Nick Ambrose wrote:

> std::string by not having a virtual destructor, is saying "do not publicly derive from
> me - it may not be safe" and you went and publicly derived from it. OK, in the vast
> majority of use, it all works out ok.
> However, what if a developer comes along and says....
> std::map<int,string *> MyStringMap;
>  - looks reasonable ? well, if you put in MyString pointers, it's not necessarily.
> When you delete the memory as you clean the map out, you are going to invoke undefined
> behaviour.

 Nick, I did agree with you, before. But, wait a minute, when you
clear the map out, it will only delete the pointer to MyString, not
MyString. Therefore, it did not invoke undefined behavior.

 Anyway, I agree that in many cases programmers may got the objects
through factory objects or through cloning. In this case, ofcourse, the
programmers will have to delete the objects through pointer which pointing
to those objects they got. And if the pointer is of the base
without virtual destructor and the object happen to be of the derived,
then .......

 How about changing C++ to prohibit assigning the pointers to or
the references of derived objects to the pointers or references of its
base without a virtual destructor if the derived objects were dynamically
created ? That is, you can't do this

class Base {
 ...
 ~Base(); // non-virtual destructor
}

class derive : public Base {
 ~derive();
 derive* clone() { return new derive(*this) }
}

class other {
 derive* x;
 ...
 derive* getx() { return x; }
}

void func1(base*);
void func2(base&);

derive A;
other B;
derive* D = new derive;
Base* c1 = new derive; //illegal
Base* c2 = A.clone(); //illegal
Base* c3 = B.getx(); //illegal
Base* c4 = D; //illegal
func1(D); //illegal
func2(*D); //illegal

 However, these are okay.

class another {
 derive x;
 ...
 derive* get_x_addr() { return &x; }
}

another D;
Base* c = D.get_x_addr(); // fine ...
derive E;
Base* f = &E; // fine ...
Base* h = f; // fine ...
func1(&A); // fine ...
func2(A); // fine ....

derive A;
Base& B=A; // fine ...


Regards,

Waranun,




[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]