I have got some confused about shared_ptr.
Say, I have classes:
class foo {
int _f;
};
typedef std::shared_ptr<foo> fooptr;
class bar {
int _b;
};
typedef std::shared_ptr<bar> barptr;
class foobar : public foo, public bar {
int _fb;
};
int main () {
foobar *fb1 = new foobar();
foobar *fb2 = new foobar();
fooptr f((foo *)fb1);
barptr b((bar *)fb2);
return 0;
}
Because b.get() != fb2, so it should crash when the program exit? Or it is safe ?
A shared_ptr<base>
can safely take ownership of a derived*
, even if base
does not have a virtual destructor.
However, this only works if shared_ptr
knows what the most derived type of the object is when it takes ownership of it. If you were to remove the casts
fooptr f(fb1);
fooptr b(fb2);
then you'd definitely be okay. With the casts, the shared_ptr
cannot know what the most-derived type of the object is when it takes ownership of it, so the behavior is undefined, just as if you had said:
foo* f = new foobar();
delete f;
The best thing to do is to follow the rule that "a base class destructor should be either public and virtual, or protected and nonvirtual."