Effective c++學習筆記——條款5:瞭解C++默默編寫並調用哪些函數

來源:互聯網
上載者:User
       Know what functions C++ silently and calls        今天繼續學習一個條款,看到了本條款,讓我更加瞭解了C++的一些內部運行機理,思考了一番,覺得C++在這方面設計真的十分嚴密,不虧是一個很優秀的語言,讓C++一直是很受歡迎的語言。閑話少說。       每一個class都會有一個或多個建構函式、一個解構函式、一個copy assignment操作符。這些控制著基礎操作,像是產出新對象並確保它被初始化、擺脫舊對象並確保它被適當清理、以及賦予對象新值。        那麼當你當你編寫了一個empty class的時候,當你利用編譯器的對代碼進行處理的時候,它其實已經並非是一個empty  class 了。編譯器會悄悄的給你產生了 default 建構函式、一個解構函式、一個copy建構函式和一個copy assignment操作符,並且它們都是inline的。如下程式碼範例
一個自定類: class empty{}; 

其實等於以下代碼:

class Empty { public:Empty() { }//default 建構函式~Empty() { }//解構函式Empty(const Empty& rhs) { }//copy建構函式Empty& operator=(const Empty& rhs) { }//copy assignment操作符}; 

那麼這四個名詞的概念分別是:default 建構函式:在你不提供任何建構函式的情況下,系統給出的一個不帶參數,不包含函數代碼的建構函式;解構函式:與建構函式相反,當對象脫離其範圍時(例如對象所在的函數已調用完畢),系統自動執行解構函式。解構函式往往用來做“清理善後” 的工作(例如在建立對象時用new開闢了一片記憶體空間,應在退出前在解構函式中用delete釋放)。copy建構函式:只有單個形參,而且該形參是對本類類型對象的引用(常用const修飾),這樣的建構函式成為建構函式(C++ pirmer定義)。經常被稱作X(const X&),而且也是由編譯自動調用。copy assignment操作符:自動合成的一種賦值操作符 什麼時候會調用copy建構函式
以下三種情況出現時,會調用一個類的拷貝建構函式:
1) 用一個已經執行個體化了的該類對象,去執行個體化該類的另外一個對象;
2) 用該類的對象傳值的方式作為一個函數的參數;
3) 一個函數傳回值為該類的一個對象。如下代碼進行了樣本:

// five.cpp : 定義控制台應用程式的進入點。//#include "stdafx.h"#include <iostream>using namespace std;class myClass{public:     myClass():a(1),b(1){}     myClass(int m, int n)     {        a = m;        b = n;}    myClass(myClass& x)    {        a = x.a;        b = x.b;        cout << "copy constructor is called." << endl;    }    friend int someFun1(myClass x);    friend myClass someFun2(int a, int b);private:    int a;    int b;};int fun1(myClass x){    return x.a + x.b;}myClass fun2(int a, int b){    myClass ca(a, b);    return ca; }int _tmain(int argc, _TCHAR* argv[]){    myClass a;//調用已經聲明的建構函式    myClass c(10, 10);    myClass d(c); // 情況1)     int anInt = fun1(c); // 情況2    myClass e = fun2(11, 11); // 情況3    return 0;}

什麼時候必須要顯式聲明拷貝建構函式?
拷貝建構函式的作用就是用一個已經執行個體化了的該類對象,去執行個體化該類的另外一個對象。下面的代碼並沒有顯式聲明一個建構函式,編譯器會自動為類BaseClass產生一個預設的隱式拷貝建構函式:

// five.cpp : 定義控制台應用程式的進入點。//#include "stdafx.h"#include <iostream>using namespace std;class BaseClass {private:    int a;public:    BaseClass(int b){a = b;}    void SetValue(int a){this->a = a;}    void Show(){cout << a << endl;}};int _tmain(int argc, _TCHAR* argv[]) {    BaseClass base(100);    BaseClass dev = base; // 調用了預設的隱式拷貝建構函式    BaseClass bc(dev); // 調用了預設的隱式拷貝建構函式    dev.Show(); // 輸出應該是100    dev.SetValue(90);    dev.Show(); // 輸出應該是90    base.Show(); // 輸出應該是100    bc.Show(); // 輸出應該是100    return 0;}

           注意,編譯器產出的解構函式是個non-virtual(見條款7),除非這個class的base class自身聲明有virtual解構函式(這種情況下這個函數的虛屬性。什麼時候不會自動調用copy assignment操作符?       至於copy建構函式和copy assignment操作符,編譯器建立的版本只是單純地將來來源物件的每一個non-static成員變數拷貝到目標對象。但在某些情況下編譯器拒絕產生copy assignment操作符函數。比如存在引用成員和const成員。對於引用的改變,也就是說引用自身可被改動嗎?如果是,那麼就違背了C++的原則:引用不能修改指向對象。所以必須自己定義copy
assignment操作符。比如如下代碼:

// five.cpp : 定義控制台應用程式的進入點。//#include "stdafx.h"#include <iostream>using namespace std;class Person {public:    Person(string& a, const int& b)         : name(a), id(b) { }private:    const int id;    string& name;};int _tmain(int argc, _TCHAR* argv[]) {    Person p1(string("chu"), 1);    Person p2(string("jun"), 2);    p1 = p2;/////// error C2582: 'operator =' function is unavailable in 'Person'    system("pause");    return 0;} 

        還有一種情況編譯器不會產生copy assignment函數,就是基底類型將copy assignment聲明為private,衍生類別型就無法獲得編譯器的協助。因為衍生類別型無法調用基底類型的copy assignment函數(不具備存取權限)。

#include "stdafx.h"#include <iostream>using namespace std;class BaseClass {private:    BaseClass& operator=(const BaseClass& rhs) { }};class derived : public BaseClass { };int _tmain(int argc, _TCHAR* argv[]) {    BaseClass px1, px2;    px1 = px2; ///// 'BaseClass::operator =' : cannot access private member declared in class 'BaseClass'    system("pause");    return 0;}

  經過以上講解,想必大家已經對這四個default建構函式,copy建構函式,copy assignment操作符,以及解構函式的概念已經有足夠的清晰了~所以

請記住

編譯器可以暗自為class建立default建構函式,copy建構函式,copy assignment操作符,以及解構函式。

聯繫我們

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