Sign in to follow this  

RAII and smart pointers

This topic is 2042 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Can someone give me a few simple to understand examples of RAII and smart pointers? I read somewhere that RAII and smart pointers should be used for everything but other places say that pointers are useless and you should use references instead. For my part I don't know of any uses for pointers aside from passing values between functions economically or iterating through a linked list. Any major uses beside those?

Also in the examples of RAII I'm looking at all it is seems to be a class file with an empty constructor and empty destructor. Is it really that simple? Edited by Jarwulf

Share this post


Link to post
Share on other sites
Uhm... try to use polymorphism without pointers. Ok, references, but how often do you see code like
Object& obj = *(new DerivedObject);

Not to mention the cleanup:
delete &obj;

Besides, there is no such thing as "smart references" to help you avoid memory leaks and accessing invalid objects. Apart from that, pointers and references have only a few differences under the hood. It's not like they are doing completely different things. References are more convenient in syntax and unless someone deliberately does something stupid you shouldn't have to worry about them being valid.

RAII examples? Sure. std::fstream, std::vector and pretty much anything that keeps track of its resources and releases them when going out of scope. Like scoped_lock or unique_ptr.

If the constructor and destructor is really empty, it has little to do with RAII. Apparently the object doesn't "acquire" any resources during initialization and has nothing to release on destruction. That would be like calling an empty chassis an example of a light weight car.


An example for RAII and smart pointers.

[code]
//without
char* tmpBuffer = new char[chunkSize];
mutex.lock();

loadData(tmpBuffer);

mutex.unlock();
delete[] tmpBuffer;
[/code]

Oh no, loadData just threw an exception. I must ensure proper cleanup in all cases.


[code]
//without
char* tmpBuffer = new char[chunkSize];
mutex.lock();

try
{
loadData(tmpBuffer);
}
catch (...) //and I don't really know what kind of exception to expect
{
mutex.unlock();
delete[] tmpBuffer;
}
mutex.unlock();
delete[] tmpBuffer;
[/code]


How about doing it the smart way (without a mess)?

[code]
vector<char> tmpBuffer(chunkSize);
scoped_lock lock(mutex);

loadData(&tmpBuffer[0]);
[/code]

See? No cleanup, no mess to deal with exceptions, no chance of someone screwing it up by spamming early returns all over your function.

Share this post


Link to post
Share on other sites
I generally don't use "pure" smart pointers (reference counted pointers that delete themselves) because in my opinion they muddle the concept of what owns the object and manages its lifetime. For most objects that have a complex lifetime that would require smart pointers, I find it makes sense to have something manage the lifetime of that object. That can involve reference counting pointers, but not ones that delete themselves automatically.

Share this post


Link to post
Share on other sites

This topic is 2042 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this