Wednesday, June 13, 2007

use objects to manage resources

make sure that any resource allocated is always released ( think network connections, database connections, file handlers, lock, mutex, memory, other things)

mistakes are easy:
//createInvestment is a factory function that returns a investment object
int foo()
{
Investment * prt = createInvestment();
complex code that might return somehow ( think if /else/exception throw/code changed by someone/ some function that it called was "enhanced")

delete prt
}

so always use an object to manager resources.

STL auto_ptr is a good thing to use when resource is only used within a single block or function only.
e.g

int foo()
{
std::auto_ptr prt( createInvestment());
......
}


Two critical aspects:
Resource are acquired and immediately turned over to resource managing objects
resource managing objects use their destructors to make sure that resources are released ....since destructor wud be called when control leaves the block, so resources are automatically released. this can get tricky with exceptions being thrown in destructor's( something u shud never do..item 8)

coming back to auto_ptrs
auto_ptrs automatically delete whatever they were pointing to at the end
so when u copy a auto_ptr into another the first one looses its value, for e.g.

auto_ptr < inv..> * ptr(new...)
ptr2 = ptr1;
///ptr1 is null here

so you cant have auto_ptrs containers ( vector/list etc of auto_ptrs) since stl containers expect normal copying behavior

Another alternative to auto_ptrs is Reference counting smart pointer.
How does RCSP's differ from garbage collection -- cant break cycles of refererences

these can be used in stl containers

their is tr1:shared_ptr also which gives you RCSP behavior

Note that both tr1 and auto use delete in their implementation so so you cannt pass them arrays ( vector etc are good)

e.g.
std::auto_ptr aps(new std::string[10]); this is bad since delete wud be called and not delte[] which is the right destructor to call.

So basically if you are releasing resources manually then you have done something wrong.

mostly auto or tr1 can help you out.


things to remember:
to prevent resource leaks, use RAII objects tha acquire resources in their constructors and release them in their destructors
two commonly useful RAII classes are tr1::shared_ptr and auto_ptr tr1::shared_ptr is usually the better choice , because its behavior when copied is intuitive., copying an auto_ptr sets it to null

No comments: