auto_ptr 智慧指標
auto_ptr是現在標準庫裡面一個輕量級的智慧指標的實現,存在於標頭檔案 memory中,之所以說它是輕量級,是因為它只有一個成員變數(擁有物件的指標),相關的呼叫開銷也非常小。
void g()
{
T* pt1 = new T;
// right now, we own the allocated object
// pass ownership to an auto_ptr
auto_ptr<T> pt2( pt1 );
// use the auto_ptr the same way
// we'd use a simple pointer
*pt2 = 12; // same as "*pt1 = 12;"
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
pt2->SomeFunc(); // same as "pt1->SomeFunc();"
// use get() to see the pointer value
assert( pt1 == pt2.get() );
// use release() to take back ownership
T* pt3 = pt2.release();
// delete the object ourselves, since now
// no auto_ptr owns it any more
delete pt3;
}
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
}
void h()
![](https://i.iter01.com/images/734cf992c50c94f42216b4cf01215e5b06e3f9e40c5ce920c4a91880732ba8a9.gif)
...{
auto_ptr<T> pt( new T(1) );
pt.reset( new T(2) );
// deletes the first T that was
// allocated with "new T(1)"
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
} // finally, pt goes out of scope and
![](https://i.iter01.com/images/734cf992c50c94f42216b4cf01215e5b06e3f9e40c5ce920c4a91880732ba8a9.gif)
![](https://i.iter01.com/images/c3ffe7f5b49223f28337e6209ea63ae8be275b3004c27dcfe5a788ca12d38bea.gif)
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
![](https://i.iter01.com/images/94ad58376cb2a689507716380b48ecde952599e8369d40c85852c86d0efe4084.gif)
![](https://i.iter01.com/images/811e8c650021147a11339541acecd9efbac33035c118639f0a8015f0cb2e2aa6.gif)
}
從上面的例子來看,auto_ptr的使用很簡單,通過建構函式擁有一個動態分配物件的所有權,然後就可以被當作物件指標來使用,當auto_ptr物件被銷燬的時候,它也會自動銷燬自己擁有所有權的物件(嗯,標準的RAAI做法),release可以用來手動放棄所有權,reset可用於手動銷燬內部物件。
auto_ptr的物件所有權是獨佔性的
這決定了不可能有兩個auto_ptr物件同時擁有同一動態物件的所有權,從而也導致了auto_ptr的拷貝行為是非對等的,其中伴隨著物件所有權的轉移。
我們仔細觀察auto_ptr的原始碼就會發現拷貝構造和賦值操作符所接受的引數型別都是非const的引用型別(auto_ptr<_Ty>& ),而不是我們一般應該使用的const引用型別
拷貝過程中被拷貝的物件(_Right)都會被呼叫release來放棄所包括的動態物件的所有權,動態物件的所有權被轉移了,新的auto_ptr獨佔了動態物件的所有權。也就是說被拷貝物件在拷貝過程中會被修改,拷貝物與被拷貝物之間是非等價的。這意味著如下的程式碼是錯誤的
同時也不要將auto_ptr放進標準庫的容器中,否則在標準庫容器無準備的拷貝行為中(標準庫容器需要的拷貝行為是等價的),會導致難以發覺的錯誤
auto_ptr特殊的拷貝行為使得使用它來遠距離傳遞動態物件變成了一件十分危險的行為,在傳遞的過程中,一不小心就會留下一些實際為空但程式本身卻缺少這樣認知的auto_ptr物件
簡單的說來,auto_ptr適合用來管理生命週期比較短或者不會被遠距離傳遞的動態物件,使用auto_ptr來管理動態分配物件,最好是侷限於某個函式內部或者是某個類的內部。也就是說,動態物件的產生,使用和銷燬的全過程是處於一個小的受控的範圍,而不會在其中加入一些適應未來時態的擴充套件。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10697500/viewspace-531785/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 智慧指標指標
- [CPP] 智慧指標指標
- 什麼是智慧指標?為什麼要用智慧指標?指標
- C++智慧指標C++指標
- openfoam 智慧指標探索指標
- 智慧指標之手撕共享指標shared_ptr指標
- 智慧指標用法學習指標
- UE4 智慧指標指標
- 指標+AI:邁向智慧化,讓指標應用更高效指標AI
- C++ 用智慧指標這樣包裝 this 指標是否可行C++指標
- C++11智慧指標用法C++指標
- C++進階(智慧指標)C++指標
- 智慧指標和普通指標的區別指標
- C++標準庫有四種智慧指標C++指標
- c++ 智慧指標用法詳解C++指標
- C++筆記(11) 智慧指標C++筆記指標
- 智慧指標-使用、避坑和實現指標
- C++基於模板實現智慧指標C++指標
- 【C++】智慧指標的正確使用方式C++指標
- 智慧指標引用計數變化學習指標
- 詳解c++指標的指標和指標的引用C++指標
- C語言指標(三):陣列指標和字串指標C語言指標陣列字串
- 陣列指標,指標陣列陣列指標
- 指標指標
- 【C++】 61_智慧指標類别範本C++指標
- 聊聊 C++ 中的幾種智慧指標 (上)C++指標
- c++11新特性實戰(二):智慧指標C++指標
- 指標陣列與陣列指標指標陣列
- 指標函式 和 函式指標指標函式
- 第 10 節:複合型別-5. 指標 -- 指標與指標變數 -8. 多級指標型別指標變數
- C指標原理(14)-C指標基礎指標
- C指標原理(15)-C指標基礎指標
- 指標常量和常量指標的區別指標
- C++智慧指標學習——小談引用計數C++指標
- Rust 程式設計影片教程(進階)——009 智慧指標Rust程式設計指標
- c++智慧指標中的reset成員函式C++指標函式
- c++動態記憶體管理與智慧指標C++記憶體指標
- 達成智慧數字經營的指標有哪些?指標
- 智慧網聯建設核心評價指標探討指標