Boost logo

Boost Users :

Subject: [Boost-users] Does shared_ptr support interface pointers without a virtual destructor
From: John Selbie (jselbie_at_[hidden])
Date: 2014-12-14 15:31:59


What is the general guidance with using shared_ptr on interfaces that do not have virtual destructor?

Take the following code sample:
class IFoo{public: virtual void M1() = 0;};
class Foo : public IFoo{public: void M1() {} Foo() { std::cout << "Foo constructor\n";} ~Foo(){std::cout << "~Foo destructor\n";}};

I think we all know that this is not safe:
{ IFoo *pFoo = new Foo(); delete pFoo;}
Since IFoo is missing a virtual destructor, then ~Foo() will not be invoked in the above case.

So let's switch to using std::shared_ptr
{ std::shared_ptr<IFoo> spFoo(new Foo());}
std::shared_ptr has a templated constructor that creates a "deleter". So when "spFoo" goes out of scope, the ~Foo destructor is properly invoked even though it's of type shared_ptr<IFoo>. But since my code targets older compilers, I have made use of Boost. But attempting this:
{ boost::shared_ptr<IFoo> spFoo(new Foo());}
Generates a lot of scary warnings when compiling with -Wall.
In file included from /home/jselbie/boost_1_57_0/boost/checked_delete.hpp:15:0, from /home/jselbie/boost_1_57_0/boost/smart_ptr/shared_ptr.hpp:26, from /home/jselbie/boost_1_57_0/boost/shared_ptr.hpp:17, from main.cpp:9:/home/jselbie/boost_1_57_0/boost/core/checked_delete.hpp: In instantiation of ‘void boost::checked_delete(T*) [with T = Foo]’:/home/jselbie/boost_1_57_0/boost/smart_ptr/detail/shared_count.hpp:134:38: required from ‘boost::detail::shared_count::shared_count(Y*) [with Y = Foo]’/home/jselbie/boost_1_57_0/boost/smart_ptr/shared_ptr.hpp:271:47: required from ‘void boost::detail::sp_pointer_construct(boost::shared_ptr<X>*, Y*, boost::detail::shared_count&) [with T = IFoo; Y = Foo]’/home/jselbie/boost_1_57_0/boost/smart_ptr/shared_ptr.hpp:349:58: required from ‘boost::shared_ptr<T>::shared_ptr(Y*) [with Y = Foo; T = IFoo]’main.cpp:36:44: required from here/home/jselbie/boost_1_57_0/boost/core/checked_delete.hpp:34:5: warning: deleting object of polymorphic class type ‘Foo’ which has non-virtual destructor might cause undefined behaviour [-Wdelete-non-virtual-dtor]

Now despite the warning about the non virtual destructor, the correct behavior of having ~Foo() invoked works. The interesting thing is that marking the destructor of the *derived* class (virtual ~Foo) makes the warning go away. It's like it's warning me that if I ever inherit from Foo, then I might run into issues - not of any immediate problems.
Should I never user shared_ptr with interface pointers that lack a virtual destructor? Always declare a virtual destructor? What is the guidance here?
jrs

                                               



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net