Delete with a pointer to Derived, not Base

I implemented a base class of smart pointers. It works for the following type of code. (given that Base1 has an open constructor)

Sptr<Base1> b(new Base1);
b->myFunc();
{
    Sptr<Base1> c = b;
    Sptr<Base1> d(b);
    Sptr<Base1> e;
    e = b;
}

But in the test code, it has a protected constructor (I need this to be the case). and code

Sptr<Base1> sp(new Derived);

It produces the following error (note Derived):

Sptr.cpp: In instantiation ofmy::Sptr<T>::~Sptr() [with T = Base1]’:
Sptr.cpp:254:39:   required from here
Sptr.cpp:205:9: error: ‘Base1::~Base1()’ is protected
Sptr.cpp:97:17: error: within this context

The problem is that I have to make sure that you delete the pointer to Derived, not Base1. How can i do this?

Here is the class code (trimmed to show constructor, distructor and class members)

template <class T>
class Sptr {
private:
   T* obj; // The actual object pointed by
       RC* ref;// A reference object to keep track of count
public:
  //declarations


template <typename T>
Sptr<T>::Sptr():obj(NULL),ref(NULL) {
    //do something
    std::cout<<"()\n";
    ref = new RC();
    ref->AddRef();
}

template <typename T>
Sptr<T>::Sptr(const Sptr &a) : obj(a.obj),ref(a.ref) {
    //do something
    std::cout<<"const Sptr\n";
    ref->AddRef();
}

template <typename T>
Sptr<T>::~Sptr() {
    //do something
    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 something
    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 is not virtual. This is what I have to decide. Below are the classes Base1andDerived

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;
};
-1
source share
1 answer

, , , (, ). ( ), shared_ptr<>. , SFINAE , , .

+2

All Articles