dan*_*jar 15 c++ reference-counting void-pointers shared-ptr
我想保持聪明的行为std::shared_ptr.那么有没有办法将共享的void指针转换为另一种类型而不会混淆引用计数?我无法获取原始指针并从中创建新的共享指针.
Bil*_*eal 21
您可以使用rob mayoff的答案中的指针强制转换; 不过要小心.这里很容易无意中触发未定义的行为:
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;
Run Code Online (Sandbox Code Playgroud)
通常,这种未定义的行为将导致不调用类型的析构函数.例如,请参阅ideone上的输出,并注意放入的版本void*永远不会打印它被销毁.
参见C++ 11 5.3.5 [expr.delete]/3:
在第一个备选(删除对象)中,如果要删除的对象的静态类型与其动态类型不同,则静态类型应为要删除的对象的动态类型的基类,静态类型应具有虚拟析构函数或行为未定义.
由于实际物体将永远不会有一个动态的类型void,并且void从来都不是一个基类动态类型的,delete荷兰国际集团一个void*触发器未定义行为.