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.

- 32,406
- 45
- 166
- 297
-
2Possible duplicate of http://stackoverflow.com/questions/6795629/how-does-one-downcast-a-stdshared-ptr – Billy ONeal Sep 16 '14 at 00:35
-
@BillyONeal: No, `void` is not a base class of all types. C++ isn't that pure OO. – MSalters Sep 16 '14 at 09:13
-
@MSalters: that's why I wrote the comment rather than actual voting to close (I did not want want to do that unilaterally) – Billy ONeal Sep 16 '14 at 14:34
2 Answers
You can use std::static_pointer_cast
or std::dynamic_pointer_cast
depending on what kind of cast you want.

- 104,103
- 58
- 317
- 552

- 375,296
- 67
- 796
- 848
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, delete
ing a void*
triggers undefined behavior.

- 1
- 1

- 104,103
- 58
- 317
- 552
-
A previous version of this answer had an incorrect `shared_ptr exampleVoid(new MyClass)` portion which I have now fixed. Feel free to remove upvotes for putting my foot in my mouth :P – Billy ONeal Sep 16 '14 at 01:12
-
1+1 for providing a more complete answer, also recognizing you made a mistake, admitting and fixing it should be encouraged, most of us are here to learn and that is part of the process. – Shafik Yaghmour Sep 16 '14 at 01:15
-
1I'm cross because you deleted the answer for editing just as I was writing a comment regarding the incorrect example ;-) – Steve Jessop Sep 16 '14 at 01:30
-