Is there a way to cast shared_ptr<void> to shared_ptr<T>?

余生长醉 提交于 2019-12-18 14:14:31

问题


I want to keep the smart behavior of std::shared_ptr. So is there a way to cast a shared void pointer to another type while without confusing the reference counting? I can't get the raw pointer and create a new shared pointer from it.


回答1:


You can use the pointer casts from rob mayoff's answer; but be careful. It is easy to unintentionally trigger undefined behavior here:

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;

Typically this undefined behavior will result in the type's destructor not being called. For example, see the output on ideone and note that the version put into a void* never prints that it was destroyed.


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

In the first alternative (delete object), if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined.

Since the actual object will never have a dynamic type void, and void is never a base class of a dynamic type, deleteing a void* triggers undefined behavior.




回答2:


You can use std::static_pointer_cast or std::dynamic_pointer_cast depending on what kind of cast you want.



来源:https://stackoverflow.com/questions/25858939/is-there-a-way-to-cast-shared-ptrvoid-to-shared-ptrt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!