shared_ptr<void>
的特殊之处在于,通过定义,它将通过调用delete
上的void*
来调用未定义的行为。
那么,为什么没有shared_ptr<void>
特化引发编译错误?
答案 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强制转换回正确的类型。
答案 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
构造函数的情况下,您应该收到编译错误。