【发布时间】:2018-10-23 18:40:07
【问题描述】:
shared::ptr我发现的实现是这样写的
namespace detail {
struct deleter_base {
virtual ~deleter_base() {}
virtual void operator()( void* ) = 0;
};
template <typename T>
struct deleter : deleter_base {
virtual void operator()( void* p ) {
delete static_cast<T*>(p);
}
};
}
template <typename T>
class simple_ptr {
T* ptr;
detail::deleter_base* deleter;
public:
template <typename U>
simple_ptr( U* p ) {
ptr = p;
deleter = new detail::deleter<U>();
}
~simple_ptr() {
(*deleter)( ptr );
delete deleter;
}
};
我的问题是
1) 为什么我们需要这样的结构(我的意思是类型擦除技术),我们不能把它作为删除器(见下面的代码)吗?在这里有一个虚函数的目的是什么,据我所知,如果它不是虚拟的,它无论如何都会在正确的类型上调用delete(即在Bar 上输入std::shared_ptr<Foo>(new Bar)),因为simple_ptr 已模板化构造函数。
template <typename T>
struct deleter {
void operator()( void* p ) {
delete static_cast<T*>(p);
}
};
2) 为什么我们需要在基类中使用虚拟析构函数?仅仅是因为它包含一个虚函数还是我们的删除器也必须有虚析构函数?
【问题讨论】:
-
您的第二个问题在这里得到解答:stackoverflow.com/questions/461203/…
-
您的示例适用于只需要一个函数即可工作的琐碎删除器,但如果您想要一个具有某种状态或持久数据的删除器,那么您的示例将不起作用,而多态选项会。
-
您的
deleter<T>不能存储在simple_ptr中,因为没有任何类型(除了void*)可以为任何deleter<T>存储T。在void*中,它不能被调用。所以我不确定你在问什么。 -
@Yakk-AdamNevraumont 啊,非常感谢,我没有意识到我什至不能用这种方式存储它,现在我清楚为什么我们需要这个抽象类了 :)
标签: c++ templates shared-ptr virtual-functions