2007年7月9日 星期一

Boost Pointer Container

http://www.boost.org/libs/ptr_container/doc/ptr_container.html

顧名思義就是存放pointer的container,exception-safe。以前我們會用這樣的方法來存放pointer:

std::vector<MyClass*> myvector;
myvector.push_back(new MyClass());
myvector[0]->do_something();

上面這段code還沒寫完喔,因為我們存的是pointer,所以之後還要去注意釋放那些pointer所allocate的memory。

現在Boost Pointer Container裡面有個ptr_vector可以對應std::vector

boost::ptr_vector<MyClass> myvector;
myvector.push_back(new MyClass());
myvector[0].do_something();

code有點不一樣,可以看到的是,我們無法從Pointer Container取回pointer了,這可以避免一些意外情況發生。另外,所有的Pointer Container都會在解構時自動釋放pointer所佔的記憶體。

看到這邊有人可能會想:不過是自動釋放記憶體嘛......我自己寫code都很細心,都會注意memory的釋放,這個pointer container沒多大用處嘛。不過,Pointer Container最重要的重點是exception-safe,何謂exception-safe?參考下面這一段code:

void func()
{
std::vector<MyClass*> myvector;
myvector.push_back(new MyClass());

try
{
// Exceptions may occur here
}
catch(...)
{
throw;
}

// I'm a good programmer
delete myvector[0];
}

在exception發生時,還沒到釋放memory的地方就跳出function了,這裡就會造成memory leak。雖然我們可以在catch裡都加上處理記憶體問題的code,但這樣的作法可能會非常的tedious(沒有人會想在每個catch裡都寫一次release memory的code吧?)。所以,有人會用std::auto_ptr或boost::shared_ptr這種smart pointer來解決這種問題:

std::vector<boost::shared_ptr<MyClass> > myvector;

C++ exception handling保證跳出function以前,所有的stack object都會被正常清除。所以上述的smart pointer都能夠保證在exception發生時,自動釋放pointer所指的memory。不過,使用smart pointer會多出一些overhead,而Pointer Container內部的實做則是直接將指標轉換成void*來儲存,顯然比smart pointer的效率要高。

基本上每個STL container在Boost Pointer Container都有互相對應的類別可以使用,例如vector對應ptr_vector,map對應ptr_map,操作方法也一樣,還擴充了一些便利的方法,例如我們可以直接用ptr_map.insert(k, v),不必像以前的std::map還要先create出一個pair object。

沒有留言: