日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

auto_ptr使用介绍

發布時間:2025/4/5 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 auto_ptr使用介绍 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1 auto_ptr使用介紹
    • 2 auto_ptr的弊端

1 auto_ptr使用介紹

auto_ptr 是c++ 98定義的智能指針模板,其定義了管理指針的對象,可以將new 獲得(直接或間接)的地址賦給這種對象。當對象過期時,其析構函數將使用delete 來釋放內存!

使用建議:

  • 盡可能不要將auto_ptr 變量定義為全局變量或指針。
  • 除非自己知道后果,不要把auto_ptr 智能指針賦值給同類型的另外一個智能指針。
  • C++11 后auto_ptr 已經被“拋棄”,已使用unique_ptr替代!
  • 示例代碼如下:

    #include <iostream> #include <string> #include <exception> #include <memory>using namespace std;//auto_ptr< Test> t(new Test()); //忠告1: 智能指針不要定義為全局變量class Test { public:Test() {cout << "Test is construct" << endl;debug = 1; }~Test() { cout << "Test is destruct" << endl; }int getDebug() {return debug;}private:int debug; };//用 法: auto_ptr<類型> 變量名(new 類型)void memory_leak_demo1() {auto_ptr< Test> t(new Test());//忠告3: 除非自己知道后果,不要把auto_ptr 智能指針賦值給同類型的另外一個智能指針//auto_ptr< Test> t1;//t1 = t;//auto_ptr<Test>* tp = new auto_ptr<Test>(new Test()); //忠告2: 不要定義指向智能指針對象的指針變量//在使用智能指針訪問對象時,使用方式和普通指針一樣cout<< "-> debug: "<<t->getDebug()<< endl;cout << "* debug: " << (*t).getDebug() << endl;//Test* tmp = t.get();//cout << "get debug: " << tmp->getDebug() << endl;//release 取消指針指針對動態內存的托管,之前分配的內存必須手動釋放//Test* tmp = t.release(); //delete tmp; //reset 重置智能指針托管的內存地址,如果地址不一致,原來的會被析構掉//t.reset();t.reset(new Test());if(0){Test* t1 = new Test();t1->getDebug();}return;}int memory_leak_demo2() {//Test* t = new Test();auto_ptr< Test> t(new Test());/************************************************ 程序執行一段復雜的邏輯,假設嘗試從一個必須存在* 的文件中讀取某些數據,而文件此時不存在************************************************/{throw exception("文件不存在");}//delete t;return 0; }int main() {memory_leak_demo1();/*try {memory_leak_demo2();}catch (exception e) {cout << "catch exception: " << e.what() << endl;}*/system("pause");return 0; }

    auto_ptr的源碼如下,雖然不能完全看懂還是貼在這里:

    #if _HAS_AUTO_PTR_ETC // CLASS TEMPLATE auto_ptr template <class _Ty> class auto_ptr;template <class _Ty> struct auto_ptr_ref { // proxy reference for auto_ptr copyingexplicit auto_ptr_ref(_Ty* _Right) : _Ref(_Right) {}_Ty* _Ref; // generic pointer to auto_ptr ptr };template <class _Ty> class auto_ptr { // wrap an object pointer to ensure destruction public:using element_type = _Ty;explicit auto_ptr(_Ty* _Ptr = nullptr) noexcept : _Myptr(_Ptr) {}auto_ptr(auto_ptr& _Right) noexcept : _Myptr(_Right.release()) {}auto_ptr(auto_ptr_ref<_Ty> _Right) noexcept {_Ty* _Ptr = _Right._Ref;_Right._Ref = nullptr; // release old_Myptr = _Ptr; // reset this}template <class _Other>operator auto_ptr<_Other>() noexcept { // convert to compatible auto_ptrreturn auto_ptr<_Other>(*this);}template <class _Other>operator auto_ptr_ref<_Other>() noexcept { // convert to compatible auto_ptr_ref_Other* _Cvtptr = _Myptr; // test implicit conversionauto_ptr_ref<_Other> _Ans(_Cvtptr);_Myptr = nullptr; // pass ownership to auto_ptr_refreturn _Ans;}template <class _Other>auto_ptr& operator=(auto_ptr<_Other>& _Right) noexcept {reset(_Right.release());return *this;}template <class _Other>auto_ptr(auto_ptr<_Other>& _Right) noexcept : _Myptr(_Right.release()) {}auto_ptr& operator=(auto_ptr& _Right) noexcept {reset(_Right.release());return *this;}auto_ptr& operator=(auto_ptr_ref<_Ty> _Right) noexcept {_Ty* _Ptr = _Right._Ref;_Right._Ref = 0; // release oldreset(_Ptr); // set newreturn *this;}~auto_ptr() noexcept {delete _Myptr;}_NODISCARD _Ty& operator*() const noexcept { #if _ITERATOR_DEBUG_LEVEL == 2_STL_VERIFY(_Myptr, "auto_ptr not dereferencable"); #endif // _ITERATOR_DEBUG_LEVEL == 2return *get();}_NODISCARD _Ty* operator->() const noexcept { #if _ITERATOR_DEBUG_LEVEL == 2_STL_VERIFY(_Myptr, "auto_ptr not dereferencable"); #endif // _ITERATOR_DEBUG_LEVEL == 2return get();}_NODISCARD _Ty* get() const noexcept {return _Myptr;}_Ty* release() noexcept {_Ty* _Tmp = _Myptr;_Myptr = nullptr;return _Tmp;}void reset(_Ty* _Ptr = nullptr) noexcept { // destroy designated object and store new pointerif (_Ptr != _Myptr) {delete _Myptr;}_Myptr = _Ptr;}private:_Ty* _Myptr; // the wrapped object pointer };

    2 auto_ptr的弊端

    auto_ptr是用于C++11之前的智能指針。由于 auto_ptr 基于排他所有權模式:兩個指針不能指向同一個資源,復制或賦值都會改變資源的所有權。auto_ptr 主要有如下幾個問題:

    • 復制和賦值會改變資源的所有權,不符合人的直覺。
    • 在 STL 容器中使用auto_ptr存在重大風險,因為容器內的元素必需支持可復制(copy constructable)和可賦值(assignable)。
    • 不支持對象數組的操作。
    #include <stdio.h> #include <iostream> #include <string> #include <memory> #include <vector>using namespace std;int main() {//弊端1. auto_ptr 被C++11 拋棄的主要理由 p1= p2 ,復制或賦值都會改變資源的所有權auto_ptr<string> p1(new string("I 'm martin."));auto_ptr<string> p2(new string("I 'm rock."));printf("p1: %p\n", p1.get());printf("p2: %p\n", p2.get());p1 = p2;printf("after p1 = p2\n");printf("p1: %p\n", p1.get());printf("p2: %p\n", p2.get());//弊端2. 在 STL 容器中使用auto_ptr存在重大風險,因為容器內的元素必需支持可復制(copy constructable)和可賦值(assignable)。vector<auto_ptr<string>> va;auto_ptr<string> p3(new string("I 'm p3."));auto_ptr<string> p4(new string("I 'm p4."));va.push_back(std::move(p3));va.push_back(std::move(p4));cout <<"va[0]: "<< *va[0] << endl;cout <<"va[1]: "<< *va[1] << endl;//風險來啦va[0] = va[1];cout << "va[0]: " << *va[0] << endl;cout << "va[1]: " << *va[1] << endl;//弊端3. 不支持對象數組的內存管理//auto_ptr<int[]> ai(new int[5]); //不能這樣定義//auto_ptr 陷阱,不能把同一段內存交給多個auto_ptr 變量去管理/*{auto_ptr<string> p2;string* str = new string("智能指針的內存管理陷阱");p2.reset(str);{auto_ptr<string> p1;p1.reset(str);}cout <<"str: " << *p2 << endl;}*/system("pause");return 0; }

    所以,C++11用更嚴謹的unique_ptr 取代了auto_ptr!


    參考資料:

  • C/C++從入門到精通-高級程序員之路【奇牛學院】
  • 總結

    以上是生活随笔為你收集整理的auto_ptr使用介绍的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。