为什么shared_ptr <void>不是专门的?</void>

时间:2011-10-24 19:38:58

标签: c++ pointers

shared_ptr<void>的特殊之处在于,通过定义,它将通过调用delete上的void*来调用未定义的行为。

那么,为什么没有shared_ptr<void>特化引发编译错误?

4 个答案:

答案 0 :(得分:7)

shared_ptr<T>的特殊之处在于,它被设计为允许保存指向任何可转换为T*的指针类型的指针,并且将使用没有UB的正确删除器!这与shared_ptr<Base> p(new Derived);方案一起发挥作用,但也包括shared_ptr<void>

例如:

#include <boost/shared_ptr.hpp>

struct T {
    T() { std::cout << "T()\n"; }
    ~T() { std::cout << "~T()\n"; }
};


int main() {
    boost::shared_ptr<void> sp(new T);
}

产生输出:

$ ./test
T()
~T()

如果您访问http://www.boost.org/doc/libs/1_47_0/libs/smart_ptr/shared_ptr.htm,请向下滚动到分配部分,查看正在演示的内容。有关详细信息,请参阅http://www.boost.org/doc/libs/1_47_0/libs/smart_ptr/sp_techniques.html#pvoid

如trinithis所述

EDIT ,如果传递给构造函数的指针类型是void *指针,则 UB。谢谢你指出来了!

答案 1 :(得分:7)

  

Using shared_ptr to hold an arbitrary object

     

shared_ptr可以充当类似于void *的通用对象指针。当shared_ptr实例构造为:

shared_ptr<void> pv(new X);
     

被破坏,它将通过执行~X来正确处理X对象。

     

此属性的使用方式与原始void *用于临时从对象指针中删除类型信息的方式相同。以后可以使用static_pointer_cast将shared_ptr强制转换回正确的类型。

但是如何?

This constructor has been changed to a template in order to remember the actual pointer type passed. The destructor will call delete with the same pointer, complete with its original type, even when T does not have a virtual destructor, or is void

答案 2 :(得分:4)

如果您的指针是通过malloc之类的内容创建的,则可以shared_ptr<void, dtor> dtor调用free。这将导致定义的行为。

但话说回来,也许你想要未定义的行为:D

答案 3 :(得分:1)

但在许多情况下 有效。请考虑以下事项:

class T
{
public:
    ~T() { std::cout << "~T\n"; }
};

int main()
{
    boost::shared_ptr<void> sp(new T);
}

在您尝试将真正的void *传递到shared_ptr构造函数的情况下,您应该收到编译错误。