Smart Pointers Lesson
This is something I typed up for some colleagues and I thought it might be useful info for C++ programmers.
To create an object:
shared_ptr<TypeID> type = make_shared<TypeID>(constructor args…)
This is pretty verbose, so I always do this:
auto type = make_shared<TypeID>(constructor args…)
When all references to the shared pointer are gone, the object is instantly deleted. There’s no garbage collection pauses, and deletion is always instant:
auto thing = make_shared<Thing>(); auto second_ref = thing; thing = NULL; second_ref = NULL;//poof!
Shared pointers are fast and thread-safe. (Don’t ask me how.)
To get a shared pointer within an object’s method, you need to derive the class from “enable_shared_from_this<SharedObject>”. (You can inherit a class from multiple types, remember):
class SharedObject : public enable_shared_from_this<SharedObject>
And you can implement a Self() method like so, if you want:
shared_ptr<SharedObject> SharedObject::Self() { return shared_from_this(); }
Casting a type is done like this:
auto bird = dynamic_pointer_cast<Bird>(animal);
Dynamic pointer casts will return NULL if the animal is not a bird. Static pointer casts don’t have any checks and are a little faster I guess, but there’s no reason to ever use them.
You cannot call shared_from_this() in the constructor, because the shared pointer does not exist yet, and you cannot call it in the destructor, because the shared pointer is already gone!
Weak pointers can be used to store a value, but will not prevent the object from being deleted:
auto thing = make_shared<Thing>(); weak_ptr<Thing> thingwptr = thing; shared_ptr<Thing> another_ref_to_thing = thingwptr.lock(); //creates a new shared pointer to “thing”
auto thing = make_shared<Thing>(); weak_ptr<Thing> thingwptr = thing; thing = NULL; shared_ptr<Thing> another_ref_to_thing = thingwptr.lock(); //returns NULL!
If you want to set a weak pointer’s value to NULL without the object going out of scope, just call reset():
auto thing = make_shared<Thing>(); weak_ptr<Thing> thingwptr = thing; thingwptr.reset(); shared_ptr<Thing> another_ref_to_thing = thingwptr.lock(); //returns NULL!
Because no garbage collection is used, circular references can occur, but they are rare:
auto son = make_shared<Child>(); auto daughter = make_shared<Child>(); son->sister = daughter; daughter->brother = son; son = NULL; daughter = NULL;//nothing is deleted!
The problem above can be solved by making the sister and brother members weak pointers instead of shared pointers, thus removing the circular references.
That’s all you need to know!
- 4
2 Comments
Recommended Comments