【C++】智能指標(Smart Pointer)

來源:互聯網
上載者:User

標籤:智能指標   unique-ptr   shared-ptr   weak-ptr   auto-ptr   

1. 傳統指標存在的問題

傳統指標存在諸多的問題,比如指標所指向的對象的生命週期問題,掛起引用(dangling references),以及記憶體泄露(memory leaks).
如下是一個傳統指標的使用過程

void Foo() {    int *iPtr = new int[5];    // manipulate the memory block    // ...    // ...    // ...    delete[] iPtr;}

以上代碼將正常運行且記憶體將被合理釋放,但是使用指標常會發生一些意想不到的事情,比如訪問一個非法的記憶體單元,除0操作,以及根據一些判斷條件處理的返回return 語句。

2. 什麼是智能指標(Smart Pointer)

智能指標是RAII(Resource Acquisition is initialization)用來動態分配記憶體。它提供了普通指標的所有介面外加少數異常處理。在構造階段,它將分配記憶體,而在非其範圍內將自動釋放所佔有的記憶體。
在C++98中,使用 auto_ptr來解決上述問題。

2.1 auto_ptr
#include <iostream>#include <memory>using namespace std;class Test {public:    Test(int a = 0) : m_a(a) {}    ~Test() {        cout << "Calling destructor" << endl;    }public:    int m_a;};int main(){    auto_ptr<Test> p(new Test(5));    cout << p->m_a << endl;    return 0;}

輸出結果:

上述代碼將智能的釋放相關的記憶體。

#include <iostream>#include <memory>using namespace std;class Test {public:    Test(int a = 0) : m_a(a) {}    ~Test() {        cout << "Calling destructor" << endl;    }public:    int m_a;};void Fun(){    int a = 0, b = 5, c;    if(a == 0) {        throw "Invalid divisor";    }    c = b / a;    return;}int main(){    try {        auto_ptr<Test> p(new Test(5));        Fun();        cout << p->m_a << endl;    }    catch(...) {        cout << "Something has gone wrong" << endl;    }    return 0;}

在上述代碼中,即使異常拋出,指標照樣被正常釋放。這是因為當異常拋出時,棧鬆綁(stack unwinding)。 當所有屬於try block的本機物件被銷毀時,指標p不在範圍中而被釋放。

問題1.

至少從目前來說auto_ptr是智能的。但是它有一個非常本質的缺點:auto_ptr會傳遞它本身的ownership當其被賦值給另一個auto_ptr對象。正如下述程式所示,一個auto_ptr對象傳遞給函數Fun()中的auto_ptr對象時,其ownership,或者說是smartness將不再返回給原auto_ptr所指向的p。

#include <iostream>#include <memory>using namespace std;class Test {public:    Test(int a = 0) : m_a(a) {}    ~Test() {        cout << "Calling destructor" << endl;    }public:    int m_a;};void Fun(auto_ptr<Test> p1){    cout << p1->m_a << endl;    cout << "Fun() end" << endl;}int main(){    auto_ptr<Test> p(new Test(5));    Fun(p);    cout << p->m_a << endl;    return 0;}

運行結果:

以上程式將crash因為存在野指標auto_ptr。上述代碼奔潰的主要原因是,原先的p佔有對其自身分配記憶體的管理權。然而通過Fun()函數將其管理權轉給p1,此時因為p1的smartness,在其結束時將釋放其所指向的記憶體塊。而此時原先的p將再擁有任何記憶體,而導致在訪問時出現了null 指標,野指標的引用問題。

問題2.

auto_ptr不能使用於數組對象。 這裡的意思是不能使用於操作符new[]

int main(){    auto_ptr<Test> p(new Test[5]);    return 0;}

上述代碼將runtime error。因為對於auto_ptr而言,其調用的是delete而非delete []

問題3.

auto_ptr不能使用於一些標準的容器庫。比如vectorlistmap等等。

C++11提出了新型的智能指標,並且都賦予了其相應的意圖。

2.2 shared_ptr

未完待續…

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

【C++】智能指標(Smart Pointer)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.