c++ - delete via a pointer to Derived, not Base -
i implemented basic smart pointer class. works following type of code. (considering base1 has public constructor)
sptr<base1> b(new base1); b->myfunc(); { sptr<base1> c = b; sptr<base1> d(b); sptr<base1> e; e = b; }
but in test code has protected constructor(i need way). , code
sptr<base1> sp(new derived);
produces following error (notice derived):
sptr.cpp: in instantiation of ‘my::sptr<t>::~sptr() [with t = base1]’: sptr.cpp:254:39: required here sptr.cpp:205:9: error: ‘base1::~base1()’ protected sptr.cpp:97:17: error: within context
the problem have make sure delete via pointer derived, not base1. how can that?
here class code (clipped show constructor , distructor , class members)
template <class t> class sptr { private: t* obj; // actual object pointed rc* ref;// reference object keep track of count public: //declarations template <typename t> sptr<t>::sptr():obj(null),ref(null) { //do std::cout<<"()\n"; ref = new rc(); ref->addref(); } template <typename t> sptr<t>::sptr(const sptr &a) : obj(a.obj),ref(a.ref) { //do std::cout<<"const sptr\n"; ref->addref(); } template <typename t> sptr<t>::~sptr() { //do if(ref->release() == 0) { if(obj) delete obj; delete ref; } } template <typename t> template <typename u> sptr<t>::sptr(u* u) : obj(u),ref(null) { //do ref = new rc(); ref->addref(); } template <typename t> template <typename u> sptr<t>::sptr(const sptr<u> &u) : obj(u.obj),ref(u.ref) { std::cout<<"const sptr<u>\n"; ref->addref(); }
edit
the destructor not virtual. case have solve. below base1
, derived
classes
class base1 { protected: base1() : derived_destructor_called(false) { printf("base1::base1()\n"); } private: base1(const base1 &); // disallow. base1 &operator=(const base1 &); // disallow. protected: ~base1() { printf("base1::~base1()\n"); assert(derived_destructor_called); } protected: bool derived_destructor_called; }; class derived : public base1 { friend void basic_tests_1(); private: derived() {} derived(const derived &); // disallow. derived &operator=(const derived &); // disallow. public: ~derived() { printf("derived::~derived()\n"); derived_destructor_called = true; } int value; };
if make constructor template, can detect type of pointer passed in @ construction time , save information in smart pointer (for example, in polymorphic deleter object). (i believe) how shared_ptr<>
it. can use sfinae produce compiler error if pointer type passed in doesn't have accessible destructor.
Comments
Post a Comment