Mr. Lidström and I had an argument :)
Lidstr m先生声称,构造shared_ptr<Base> p(new Derived);不要求Base具有虚拟析构函数:
Armen Tsirunyan:“真的吗? shared_ptr清理正确吗?在这种情况下,您能演示一下如何实现这种效果吗?”
Daniel Lidstr m:“shared_ptr使用自己的析构函数删除具体实例。这在C++社区中被称为RAII。我的建议是,您应该尽可能地了解RAII。在所有情况下使用RAII都会使您的C++编码更加容易。”
Armen Tsirunyan:“我知道RAII,我也知道当pn达到0时,shared_ptr析构函数可能会删除存储的px。但是如果px有指向Base的静态类型指针和指向Derived的动态类型指针,那么除非Base有一个虚拟析构函数,否则这将导致未定义的行为。如果我错了,请纠正我。”
Daniel Lidstr m:“shared_ptr知道静态类型是具体的。它知道这一点,因为我在它的构造函数中传递了它!看起来有点神奇,但我可以向你保证,它是设计的,而且非常漂亮。”
所以,评判我们。如何才能(如果是)实现shared_ptr而不需要多态类具有虚拟析构函数?提前感谢
发布于 2010-10-10 11:18:06
是的,用这种方式实现shared_ptr是可能的。Boost does和C++11标准也要求这种行为。作为一种额外的灵活性,shared_ptr管理的不仅仅是一个引用计数器。所谓的删除器通常被放入同样包含引用计数器的内存块中。但有趣的是,这个删除器的类型不是shared_ptr类型的一部分。这被称为“类型擦除”,并且基本上是用于实现“多态函数”boost::function或std::function以隐藏实际函子类型的技术。要使示例工作,我们需要一个模板化的构造函数:
template<class T>
class shared_ptr
{
public:
...
template<class Y>
explicit shared_ptr(Y* p);
...
};所以,如果你在你的类Base和Derived中使用这个..。
class Base {};
class Derived : public Base {};
int main() {
shared_ptr<Base> sp (new Derived);
}..。带有Y=Derived的模板构造函数用于构造shared_ptr对象。因此,构造函数有机会创建适当的删除对象和引用计数器,并将指向此控件块的指针存储为数据成员。如果引用计数器达到零,则将使用先前创建的和Derived-aware删除器来释放对象。
C++11标准对此构造函数有如下说明(20.7.2.2.1):
要求:
p必须可转换为T*。Y应该是一个完整的类型。delete p一词应格式良好,行为应明确,不得抛出异常。。
效果:构造一个shared_ptr对象,拥有指针
…
以及破坏者(20.7.2.2.2):
效果:如果
*this为空或与另一个shared_ptr实例(use_count() > 1)共享所有权,则没有副作用。否则,如果*this拥有对象p和删除器d,则调用d(p)。否则,如果*this拥有指针p**,和**delete p,则为.。
(用粗体强调是我的)。
发布于 2010-10-10 09:47:53
当创建shared_ptr时,它会在其内部存储一个删除对象。当shared_ptr即将释放指定资源时,将调用此对象。由于您知道如何在构建时销毁资源,所以可以使用不完整类型的shared_ptr。创建shared_ptr的人在那里存储了一个正确的删除器。
例如,您可以创建一个自定义删除器:
void DeleteDerived(Derived* d) { delete d; } // EDIT: no conversion needed.
shared_ptr<Base> p(new Derived, DeleteDerived);P将调用DeleteDerived来销毁指向的对象。该实现自动执行此操作。
发布于 2010-10-10 09:46:02
简单地说,
shared_ptr使用由构造函数创建的特殊删除函数,构造函数总是使用给定对象的析构函数,而不是Base的析构函数,这是模板元编程中的一些工作,但它有效。
类似这样的东西
template<typename SomeType>
shared_ptr(SomeType *p)
{
this->destroyer = destroyer_function<SomeType>(p);
...
}https://stackoverflow.com/questions/3899790
复制相似问题