I have a class with function called void deallocatorFunc(ClassA *p) I want using templates make it possible to write boost::shared_ptr< ClassA > ptr(new ClassA()); instead of boost::shared_ptr< ClassA > ptr(new ClassA(), deallocatorFunc);. I want it to spread on to my class and its inheritors. How to do such thing in C++? (I really need my peculiar destructor for that special class, while I want to keep super simple API).
2 Answers
You can use specialization for your class and wrap the standard implementation. Here's a self-contained compilable example.
#include <iostream> #include <boost/shared_ptr.hpp> using namespace std; class A { public: A() { cout << "Constructing A." << endl; }; virtual ~A() { cout << "Destructing A." << endl; } }; class B : public A { public: B() { cout << "Constructing B." << endl; }; virtual ~B() { cout << "Destructing B." << endl; } }; class C { public: C() { cout << "Constructing C." << endl; }; virtual ~C() { cout << "Destructing C." << endl; } }; void deallocatorFunc(A *p) { cout << "Deallocator function." << endl; delete p; }; namespace boost { template<> class shared_ptr<A> { private: shared_ptr<void> _ptr; public: shared_ptr(A* p) : _ptr(p, deallocatorFunc) { } }; } int main( int argc, const char* argv[] ) { boost::shared_ptr<A> ptrA(new A()); boost::shared_ptr<B> ptrB(new B()); boost::shared_ptr<C> ptrC(new C()); } Output:
Constructing A. Constructing A. Constructing B. Constructing C. Destructing C. Destructing B. Destructing A. Deallocator function. Destructing A.
Note
As given, the specialization doesn't work for derived classes of A!
For that to work, you need more trickery:
1 Comment
namespace boost { template<typename myclass> class shared_ptr { }; } Enjoy your redefinition of boost::shared_ptr. Anything which includes the above code in a header will get your shared_ptr instead of boost's.
Keep in mind this will not be compatible with code which includes boost on its own!!!
9 Comments
shared_ptr and copy through the remainder.shared_ptr and copy through the remainder" because that doesn't make much sense to me. (And how would whatever that is avoid violating the ODR?)MyClass, use this version, otherwise use the generic catch-all". See gotw.ca/gotw/049.htm as a random off-the-web resource.
operator deletefor your type?