複製控制+智能指標

來源:互聯網
上載者:User

今天把c++ primer的13章看了,總結一下。

一:複製控制

1:複製控制就是複製建構函式、賦值操作符、解構函式的總稱。他們有一定的相似性,所以統稱為“複製控制”。

他們的共性是什麼呢?

a:如果自己沒定義,系統會自動合成;

b:對於類的對象成員中有指標的情況,一般都要定義這三者。而且如果要定義解構函式就一定要定義複製建構函式和賦值操作符,這個叫“三法則”。

不同點:

複製建構函式和賦值操作符如果自己定義了,系統就不會合成,但是解構函式系統始終會合成。(p-414)利用複製建構函式和賦值操作符的特點,可以對於不能夠賦值的進行避免賦值。我們可以只申明不定義,這樣可以避免系統合成,我們自己也不操作就達到了目的。

2:為什麼要用複製建構函式

什麼時候要定義複製建構函式和賦值操作符

一般來講,當類的資料成員有指標變數,或者對對象有特殊操作時需要定義複製建構函式和賦值操作符。下面是個類的資料成員有指標變數的列子。

程式如下:

#include <stdio.h>#include <string>#include <iostream>using namespace std;struct NoName{public:NoName(std::string *str_f,int i_f,double d_f):pstring(str_f),i(i_f),d(d_f){};NoName(const NoName &a){pstring=new std::string;*(this->pstring)=*(a.pstring);this->i=a.i;this->d=a.d;}public:std::string *pstring;int i;double d;};int main(){string a(4,'x');string b(4,'y');string *str_a=&a;//string和數組還不同NoName Object1(str_a,2,3.0);NoName Object2(Object1);*(Object2.pstring)=b;cout<<*(Object1.pstring)<<endl;system("pause");return 1;}

對於這種含有指標成員的類,因為在複製是只複製指標地址,所以他們其實是公用一個基的。這種改變內容而改變其他對象的內容到不可怕,可怕的是在刪除時引起的指標懸掛。

二、指標懸掛與智能指標

指標懸掛也稱為“野指標”,是只在指標所指記憶體被刪除後指標的指向不確定的情況。對於這種指標,我們其實是可以訪問的,但是得到的值不一定每次一樣,因為這時候指標指的方向其實是不定的。但是我們不能對其所指內容進行操作,比如修改裡面的值或者刪除等等。也就是說,看看可以,但是沒有操作許可權

為瞭解決指標懸掛,可以由兩種方法。

a:構造複製建構函式

這種方法是對於每個指標就行複製操作,這樣通過改變其他對象的指標就不能影響到別的。

b:利用智能指標

智能指標可以解決指標懸掛的問題,但是其不能解決因為改變一個對象的值而影響其他對象值的問題。那麼什麼是智能指標呢?在c++ primer(p-423)中很清楚的闡明了什麼是智能指標和怎麼構造一個智能指標。其代碼如下:

class U_Ptr{friend class HasPtr;U_Ptr(int *p):ip(p),use(1){}~U_Ptr(){delete ip;}int *ip;size_t use;};class HasPtr{public:HasPtr(int *p,int i):ptr(new U_Ptr(p)),val(i){}HasPtr(const HasPtr &orig):ptr(orig.ptr),val(orig.val){orig.ptr->use++;}HasPtr& operator=(const HasPtr &rhs);~HasPtr(){if(--ptr->use==0) delete ptr;}private:U_Ptr *ptr;int val;};HasPtr& HasPtr::operator =(const HasPtr &rhs){rhs.ptr->use++;if(--this->ptr->use==0)delete this;this->ptr=rhs.ptr;this->val=rhs.val;return *this;}

這裡說明一下幾點:

1:智能指標是連絡人物件和所屬單元的紐帶,其本質上是起一個過渡作用;

2:智能指標只用於HasPtr類,我們並不希望使用者用它。因此,我們把其所有資料定義為private,並且把HasPtr定義為其友元;

3:在這裡補充兩點與上沒有關係的兩個知識點

1):new U_Ptr(p)是建立一個U_Ptr對象,其參數要求是和U_Ptr的建構函式形式息息相關的;

2):友元類表達的意思是可以讓友元類中該對象訪問其類中的私人函數,也就是說任何類的成員只能其對象才可以訪問,這點是沒有商量的餘地的。

三:補充介紹一下賦值操作符和解構函式

賦值操作符和複製建構函式情況差不多,這裡略去。主要介紹一下解構函式。

1:解構函式的作用

解構函式和建構函式相對應,其是用於釋放空間的。但是因為一般系統會自動合成解構函式,那麼我們在什麼情況下還需要自己定義解構函式呢?

2:什麼時候定義解構函式

對於“對象引用或者對象指標”和“動態申請的對象”需要手動刪除,這時候一般就需要用解構函式。或者我們想在對象刪除的同時,做點其他動作,這是也可以通過解構函式完成。而其他一般都可以通過解構函式解決。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.