【发布时间】:2017-04-21 18:35:41
【问题描述】:
我知道之前有人问过这个问题:Delete an object with a protected destructor。但是,该解决方案对我不起作用。我在编译过程中仍然会出错。
我的项目也是创建智能指针,有些测试让我删除了带有受保护析构函数的对象(有些是虚拟的,有些不是),这会导致编译时错误。
我真的不知道从哪里开始解决这个问题。提前谢谢!
这是我必须做的想法:
#include <cstddef>
template<typename T> void DefaultDeleter(void *p) { delete static_cast<T*>(p); }
struct ref_counter {
int refs;
void *p;
void (*d)(void *);
};
template<typename T> class Sptr {
public:
Sptr(T *obj){
c = new ref_counter;
c->refs = 1;
c->p = static_cast<void*>(obj);
c->d = &DefaultDeleter<T>;
p = p;
}
void reset(){
(c->d)(c->p);
delete c;
}
private:
T *p;
ref_counter *c;
};
class Base{
public:
Base(){
atr = new int(1);
}
protected:
~Base(){
delete atr;
}
private:
int *atr;
};
int main(){
Base b1;
Sptr<Base> s1(&b1);
return 0;
}
此代码导致此错误:
root@resnet-230-99:~/cs440/a3# g++ test.cpp -o test
test.cpp: In function ‘int main()’:
test.cpp:43:7: error: ‘Base::~Base()’ is protected within this context
Base b1;
^~
test.cpp:35:3: note: declared protected here
~Base(){
^
test.cpp: In instantiation of ‘void DefaultDeleter(void*) [with T = Base]’:
test.cpp:17:9: required from ‘Sptr<T>::Sptr(T*) [with T = Base]’
test.cpp:44:19: required from here
test.cpp:3:53: error: ‘Base::~Base()’ is protected within this context
template<typename T> void DefaultDeleter(void *p) { delete static_cast<T*>(p); }
^~~~~~
test.cpp:35:3: note: declared protected here
~Base(){
【问题讨论】:
-
嗯,是的,
~Base()无法从DefaultDeleter访问。也许如果你有一个带有公共析构函数的Derived类和一个Derived*指针,你可以做点什么。 -
您从接受的答案中遗漏了一个非常重要的注释:我当然假设
Base的析构函数是protected而Derived的析构函数是public,如否则这个练习毫无意义。 -
不管怎样,
Sptr<Base> s1(&b1)对智能指针毫无意义,你会自动取消分配应该分配的东西。 -
[OT]:您的重置功能在共享所有权的上下文中是错误的(您不使用参考计数器)。
-
p = p;也很可疑。