在使用STL容器時避免使用具有複雜拷貝建構函式的類

2021-04-19 22:44:31 字數 1313 閱讀 4373

在使用stl容器時避免使用具有複雜拷貝建構函式的類。在向stl容器插入乙個物件時,容器類會呼叫插入類的拷貝建構函式,如果插入類的拷貝建構函式很複雜,則將直接影響效率。

那麼何謂複雜呢?比如,進行大量記憶體的拷貝,大量耗時的運算,等等,其實質就是需要做很多任務作,需使用很多資源!如下例子說明了,即使ctest類定義了從int型別變數構造的方法,但同樣在stl容器中呼叫拷貝建構函式。

#include 

#include 

class ctest

;std::ostream & operator<<(const ctest & t,std::ostream & os)

std::ostream & operator<<(std::ostream & os,const ctest & t)

int main(int argc, char * argv)

for(std::deque::const_iterator cit=queue.begin();cit!=queue.end();++cit)

std::cout<<*cit但並不意味著複雜或者說重量級的類不能使用stl容器來封裝。我們可以將問題轉化!在插入物件到容器中時,首先建立乙個「空物件」,即預設建構函式,什麼也不做,拷貝建構函式,也什麼都不做,插入成功後,使用賦值的方式來完成物件的複雜拷貝建構函式需要做的事情!

上面的例子,只能用於說明在使用stl容器時的構造函式呼叫情況,不能說明為什麼要將拷貝建構函式做成乙個輕量級的函式。下面簡單說明一下。

假設ctest內部有乙個大塊記憶體空間的屬性。一般情況下,拷貝建構函式都會將右值物件中的記憶體複製到左值物件的記憶體。然而,一般情況下,這個類應該還會具有這樣乙個建構函式ctest(char * p);(假設這大塊記憶體是乙個很大的字串幾兆甚至幾十兆)。那麼在使用stl容器時,我們可能會這樣做(假設使用前面的**的queue):queue.push_front(buff);這樣在ctest(char *p)的建構函式會複製著一大塊記憶體,再呼叫拷貝建構函式時,又會複製這塊記憶體一次,這樣會影響程式的效能,假設,需要插入很多這樣的元素,那麼程式肯定在效能上受到嚴重影響。

解決辦法:設計ctest();建構函式,什麼也不做,也許只初始化內部指標為null;設計拷貝建構函式按照正常的情況完成**,只不過,對於空物件,她已經不再有那麼多事情要做了,例如:要複製的物件其內部記憶體指標為null,完全不需要複製大塊記憶體;設計賦值運算子,完成記憶體拷貝工作:ctest & operator=(char * p);這樣就會避免大量操作在兩次構造函書中執行。

使用乙個預設建構函式,簡化stl內部類的拷貝建構函式工作,插入到stl容器後再修改類的狀態執行更為複雜的操作,這樣,避免了stl內部呼叫拷貝建構函式造成的可能影響效能的問題。

關於在STL容器list中使用find if 函式

classdisplay 現基於list 容器已經建立起具有若干節點 1 30 的list 並根據實際需要增添新的節點,要求新增的節點的 name 要和list 中所有節點的 name 不同,我想到的方案是 在呼叫 push back 之前,先對 list 進行搜尋,檢查是否已經存在和新增的節點的 ...

STL容器使用DEMO vector

code author lin yiqian created 2009 08 24 describe stl vector 使用demo include include using namespace std typedef vector int vec 列印vector void printvec...

STL容器使用DEMO multimap

code author lin yiqian created 2009 08 24 describe stl multimap 使用demo include include include using namespace std typedef multimap str mmap 列印multima...