Search code examples
c++shared-ptr

To use shared_ptr, is it safe ?


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 ?


Solution

  • 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."