通过指向Derived的指针删除,而不是Base [英] delete via a pointer to Derived, not Base
问题描述
我实现了一个基本的智能指针类。它适用于以下类型的代码。
(考虑Base1有一个公共构造函数)
I implemented a basic Smart pointer class. It works for the following type of code. (considering Base1 has a public 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 it to be this way). and the code
Sptr<Base1> sp(new Derived);
产生以下错误(注意导出):
Produces the following error (notice the Derived):
Sptr.cpp: In instantiation of ‘my::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
问题是我必须确保你通过指向Derived而不是Base1的指针删除。
The problem is I have to Make sure that you delete via a pointer to Derived, not Base1. How can I do that?
这是类代码(修改为显示构造函数和分词和类成员)
Here is the class code (clipped to show constructor and 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
析构函数不是虚拟的。这是我必须解决的情况。以下是 Base1
和派生
类
The destructor is not virtual. That is the case I have to solve. Below is the Base1
and 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;
};
推荐答案
如果使构造函数成为模板,在构造时传递的指针类型,并将该信息保存在智能指针中(例如,在多态删除对象中)。这是(我相信) shared_ptr<>
如何。如果传入的指针类型没有可访问的析构函数,您也可以使用SFINAE产生编译器错误。
If you make your constructor a template, you can detect the type of pointer passed in at construction time and save that information in your smart pointer (for example, in a polymorphic deleter object). This is (I believe) how shared_ptr<>
does it. You can probably also use SFINAE to produce a compiler error if a pointer type is passed in that doesn't have an accessible destructor.
这篇关于通过指向Derived的指针删除,而不是Base的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!