有没有办法将shared_ptr <void>强制转换为shared_ptr <t>?</t> </void>

时间:2014-09-16 00:28:32

标签: c++ shared-ptr void-pointers reference-counting

我希望保持std::shared_ptr的智能行为。那么有没有办法将共享的void指针转换为另一种类型而不会混淆引用计数?我无法获取原始指针并从中创建一个新的共享指针。

2 个答案:

答案 0 :(得分:21)

您可以使用rob mayoff's answer中的指针强制转换;不过要小心。在这里很容易无意中触发未定义的行为:

struct MyClass {};

void* rawPtr = new MyClass;
shared_ptr<void> exampleVoid(rawPtr); // Undefined behavior;
                                      // calls delete (void*)ptr;

shared_ptr<void> exampleVoidCons(new MyClass);
    // OK, calls shared_ptr<void>::shared_ptr<MyClass>(MyClass*) which
    // makes a deleter calling delete (MyClass*)ptr;

shared_ptr<MyClass> example(new MyClass); // OK, calls delete (MyClass*)ptr;

shared_ptr<void> castToVoid = static_pointer_cast<void>(example);
    // OK, shared_ptr's deleter is erased so this still calls delete (MyClass*)ptr;

通常,这种未定义的行为将导致类型的析构函数未被调用。例如,see the output on ideone并注意放入void*的版本永远不会打印它已被销毁。


参见C ++ 11 5.3.5 [expr.delete] / 3:

  

在第一个备选(删除对象)中,如果要删除的对象的静态类型与其动态类型不同,则静态类型应为要删除的对象的动态类型的基类和静态类型type应具有虚拟析构函数或行为未定义。

由于实际对象永远不会有动态类型void,并且void永远不是动态类型的基类,delete void*会触发未定义的行为

答案 1 :(得分:18)

您可以使用std::static_pointer_caststd::dynamic_pointer_cast,具体取决于您想要的演员阵容。