auto_ptr與shared_ptr


注: 從c++11開始, auto_ptr已經被標記為棄用, 常見的替代品為shared_ptr
shared_ptr的不同之處在於引用計數, 在復制(或賦值)時不會像auto_ptr那樣直接轉移所有權

auto_ptr

  • auto_ptr實際也是一種類, 擁有自己的析構函數, 生命周期結束時能自動釋放資源
  • 正因為能自動釋放資源, 特別適合在單個函數內代替new/delete的調用, 不用自己調用delete也不用擔心意外退出
  • auto_ptr對資源的擁有者只能有一個, 當兩個auto_ptr進行等於號(賦值)操作時, 等於號后面的auto_ptr將失去資源的所有權
  • 如果只是想顯示auto_ptr對應資源的信息, 而不是更改的話, 要以const auto_ptr&(const + 引用)的方式來傳遞給其它函數

賦值與安全傳遞

#include <iostream>
#include <memory>

using namespace std;
template<class T>
ostream& operator<< (ostream& os,const auto_ptr<T>& p){
    if(p.get() == NULL)
        os<<"NULL";
    else
        os<<*p;
    return os;
}
int main(int  argc,char *argv[]){
    auto_ptr<int> p(new int(42));
    auto_ptr<int> q;

    cout<<"after initialization"<<endl;
    cout<<"p:"<<p<<endl;
    cout<<"q:"<<q<<endl;
    
    q=p;
    cout<<"after assign"<<endl;
    cout<<"p:"<<p<<endl;
    cout<<"q:"<<q<<endl;

    *q += 13;
    p=q;
    cout<<"another assign"<<endl;
    cout<<"p:"<<p<<endl;
    cout<<"q:"<<q<<endl;
    return 0;
}

非安全傳遞
以下與上面的例子差不多也只是顯示auto_ptr所指對象的值, 以非const 引用的方向傳遞, 結果在函數調用中就把資源給釋放了

#include <iostream>
#include <memory>

using namespace std;
template<class T>
ostream& operator<< (ostream& os,auto_ptr<T> p){
    if(p.get() == NULL)
        os<<"NULL";
    else
        os<<*p;
    return os;
}
int main(int  argc,char *argv[]){
    auto_ptr<int> p(new int(42));
    cout<<p<<endl;

    if(p.get() == NULL)
        cout<<"after call function, p = NULL"<<endl;
    return 0;
}

shared_ptr

#include <iostream>
#include <tr1/memory>

using namespace std;

class base{
    public:
        base(){cout<<"base init"<<endl;}
        virtual ~base(){cout<<"base over"<<endl;}
        virtual void show(){cout<<"from base"<<endl;}
};

class derived: public base{
    public:
        derived(){cout<<"derived init"<<endl;}
        ~derived(){cout<<"derived over"<<endl;}
        void show(){cout<<"from derived"<<endl;}
};

int main () {
    tr1::shared_ptr<derived> ptr(new derived());
    tr1::shared_ptr<derived> ptr2(ptr);
    cout<<ptr.get()<<endl;
    cout<<ptr2.get()<<endl;

    class derived *dptr=ptr.get();
    dptr->show();

    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM