Does shared_ptr support interface pointers without a virtual destructor
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
On Monday, December 15, 2014 04:31 AM, John Selbie wrote:
What is the general guidance with using shared_ptr on interfaces that do not have virtual destructor?
http://www.boost.org/doc/libs/1_57_0/libs/smart_ptr/shared_ptr.htm#pointer_c... "[This constructor is a template in order to remember the actual pointer type passed. The destructor will call delete with the same pointer, complete with its original type, even when T does not have a virtual destructor, or is void]" You should also be good with make_shared, which is preferred. Ben
participants (2)
-
Ben Pope
-
John Selbie