Jump to content

Smart Pointers Lesson

Josh

174 views

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!

  • Like 4


2 Comments


Recommended Comments

Really great, I'm going to need this when it comes time to convert my code for the new engine. I already have some macros in place for this.

Hopefully we can see a new beta of Turbo out so I can experiment with my actors. 

Share this comment


Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...