8

Can boost::smart_ptr such as scoped_ptr and shared_ptr be used in polymorphism?

class SomeClass
{
public:
    SomeClass()
    {
        a_ptr.reset(new SubClass);
    }
private:
    boost::scoped_ptr<SuperClass> a_ptr;
}
Jonathan Livni
  • 101,334
  • 104
  • 266
  • 359
  • @Noah, I've tried and had memory leaks. I wasn't sure this was the reason, so I wanted to consult. – Jonathan Livni Jan 21 '11 at 21:12
  • 1
    Time to start looking for circular references I suppose. :) – James Jan 21 '11 at 21:14
  • 3
    @Jonathan: Is your destructor virtual? – Martin York Jan 21 '11 at 21:14
  • @Martin - Would not having a destructor in the superclass be ok? Also - it happens to be a struct, does that matter? – Jonathan Livni Jan 21 '11 at 21:20
  • 2
    @Jonathan: The `virtual` dtor needs to be int he base class. `struct` versus `class` matters not one little bit. See my updated post. – John Dibling Jan 21 '11 at 21:26
  • 1
    In fact, when using `shared_ptr`, you are almost always safe even if the base class destructor is not virtual. – James McNellis Jan 21 '11 at 21:54
  • @James: Correct (because `shared_ptr` calls the subclass's destructor, so the base class destructor can even be protected), but `scoped_ptr`'s constructor is not templatized. – Philipp Jan 21 '11 at 22:13
  • Oh. It must be almost beer-o-clock on Friday afternoon. I totally read `scoped_ptr` as `shared_ptr`. – James McNellis Jan 21 '11 at 22:16
  • 1
    @Philip - not entirely true. The shared_ptr constructor takes a "deleter" as a parameter in addition to a pointer of type T (T being any type, not the type the shared_ptr was instantiated with). This parameter defaults to calling delete on a pointer of type T (again, constructor's T, not ptr's). So, so long as you construct your shared_ptr with the most derived type it works correctly even without a virtual destructor. If you don't...then you've just stabbed yourself in the base of the skull. – Edward Strange Jan 21 '11 at 22:21

2 Answers2

6

I believe the answer is yes; boost pointers are coded such that derived classes are accepted wherever a superclass would be.

James
  • 5,355
  • 2
  • 18
  • 30
4

Yes:

#include <string>
#include <iostream>
using namespace std;
#include <boost\shared_ptr.hpp>
using namespace boost;


class Foo
{
public:
    virtual string speak() const { return "Foo"; }
    virtual ~Foo() {};
};

class Bar : public Foo
{
public:
    string speak() const { return "Bar"; }
};

int main()
{
    boost::shared_ptr<Foo> my_foo(new Bar);
    cout << my_foo->speak();
}

Output is: Bar

John Dibling
  • 99,718
  • 31
  • 186
  • 324