1. 程式人生 > >建構函式、解構函式、拷貝建構函式小結

建構函式、解構函式、拷貝建構函式小結

  1.         建構函式的定義與使用
  2. 建構函式是特殊的公有成員函式,其特徵如下:
    1.函式名與類名相同。
    2.建構函式無函式返回型別說明。注意是沒有而不是void,即什麼也不寫,也不可寫void!實際上建構函式有返回值,返回的就是建構函式所建立的物件,見5.5節。
    3.在程式執行時,當新的物件被建立,該物件所屬的類的建構函式自動被呼叫,在該物件生存期中也只調用這一次。
    4.建構函式可以過載。嚴格地講,說明中可以有多個建構函式,它們由不同的引數表區分,系
  3.  解構函式的定義
  4. 當一個物件定義時,C++自動呼叫建構函式建立該物件並進行初始化,那麼當一個物件的生命週期結束時,C++也會自動呼叫一個函式登出該物件並進行善後工作,這個特殊的成員函式即解構函式(destructor):
    1.  構函式名與類名相同,但在前面加上字元‘~’,如
    ~CGoods()。
    2.  解構函式無函式返回型別,與建構函式在這方面是一樣的。但解構函式不帶任何引數。
    3. 一個類有一個也只有一個解構函式,這與建構函式不同。解構函式可以預設。
    4. 物件登出時,系統自動呼叫解構函式。
  5.                 拷貝建構函式 
  6. 同一個類的物件在記憶體中有完全相同的結構,如果作為一個整體進行復制或稱拷貝是完全可行的。這個拷貝過程只需要拷貝資料成員,而函式成員是共用的(只有一份拷貝)。在建立物件時可用同一類的另一個物件來初始化該物件,這時所用的建構函式稱為拷貝建構函式(Copy Constructor)。
  7. 拷貝建構函式的引數——採用引用。如果把一個真實的類物件作為引數傳遞到拷貝建構函式,會引起無窮遞迴 。
      系統會自動提供,稱為預設的按成員語義支援的拷貝建構函式,每個類成員被依次拷貝,亦稱為預設的按成員初始化。按成員作拷貝是通過依次拷貝每個資料成員實現的,而不是對整個類物件按位拷貝。賦值運算子“=”稱預設的按成員拷貝賦值操作符,同類物件之間可以用“=”直接拷貝 。
            通常按成員語義支援已經足夠。但在某些情況下,它對類與物件的安全性和處理的正確性還不夠,這時就要求類的設計者提供特殊的拷貝建構函式和拷貝賦值操作符的定義。
  8.  例項:
    CGood Car1(“夏利2000”,30,98000.00);
    //呼叫三個引數的建構函式
    CGood Car2= Car1; //呼叫拷貝建構函式
    CGood Car3 ( Car1); 
    //呼叫拷貝建構函式,Car1為實參
    這樣三個物件的初始化結果完全一樣
在類定義中如果沒有顯式給出建構函式時,並不是不用建構函式,而是由系統自動呼叫預設的建構函式或預設的拷貝建構函式。如果有程式設計者定義的建構函式(包括拷貝建構函式),則按函式過載的規律,呼叫合適的建構函式
當成員函式的引數為同一類(class)的物件或它的引用,在函式體內使用引數物件的私有資料成員時,可用物件名加成員訪問操作符點號進行。從邏輯上講,每個物件有自己的成員函式,訪問同類其他物件的私有資料成員應通過該物件的公有函式,不能直接訪問。但在物理上只有一個成員函式拷貝,所以直接訪問是合理的
拷貝建構函式還在另二個方面使用:
1. 當函式的形參是類的物件,呼叫函式時,進行形參與實參結合時使用。這時要在記憶體新建立一個區域性物件,並把實參拷貝到新的物件中。
2.當函式的返回值是類物件,函式執行完成返回呼叫者時使用。理由也是要建立一個臨時物件中,再返回呼叫者。
    因為區域性物件在離開建立它的函式時就消亡了,不可能在返回呼叫函式後繼續生存,所以在處理這種情況時,編譯系統會在呼叫函式的表示式中建立一個無名臨時物件,該臨時物件的生存週期只在函式呼叫處的表示式中。所謂return 物件,實際上是呼叫拷貝建構函式把該物件的值拷入臨時物件。如果返回的是變數,處理過程類似,只是不呼叫建構函式。
  1. #include <iostream>
  2. usingnamespace std;  
  3. class CExample {  
  4. private:  
  5.      int a;  
  6. public:  
  7.       //建構函式
  8.      CExample(int b)  
  9.      { a = b;}  
  10.       //一般函式
  11.      void Show ()  
  12.      {  
  13.         cout<<a<<endl;  
  14.       }  
  15. };  
  16. int main()  
  17. {  
  18.      CExample A(100);  
  19.      CExample B = A; //注意這裡的物件初始化要呼叫拷貝建構函式,而非賦值
  20.       B.Show ();  
  21.      return 0;  
  1. }  
執行程式,螢幕輸出100。從以上程式碼的執行結果可以看出,系統為物件 B 分配了記憶體並完成了與物件 A 的複製過程。就類物件而言,相同型別的類物件是通過拷貝建構函式來完成整個複製過程的
拷貝建構函式的工作過程。
  1. #include <iostream>
  2. usingnamespace std;  
  3. class CExample {  
  4. private:  
  5.     int a;  
  6. public:  
  7.     //建構函式
  8.     CExample(int b)  
  9.     { a = b;}  
  10.     //拷貝建構函式
  11.     CExample(const CExample& C)  
  12.     {  
  13.         a = C.a;  
  14.     }  
  15.     //一般函式
  16.     void Show ()  
  17.     {  
  18.         cout<<a<<endl;  
  19.     }  
  20. };  
  21. int main()  
  22. {  
  23.     CExample A(100);  
  24.     CExample B = A; // CExample B(A); 也是一樣的
  25.      B.Show ();  
  26.     return 0;  
  27. }   

CExample(const CExample& C) 就是我們自定義的拷貝建構函式。可見,拷貝建構函式是一種特殊的建構函式,函式的名稱必須和類名稱一致,它必須的一個引數是本型別的一個引用變數
二. 拷貝建構函式的呼叫時機
在C++中,下面三種物件需要呼叫拷貝建構函式
1. 物件以值傳遞的方式傳入函式引數
  1. class CExample   
  2. {  
  3. private:  
  4.  int a;  
  5. public:  
  6.  //建構函式
  7.  CExample(int b)  
  8.  {   
  9.   a = b;  
  10.   cout<<"creat: "<<a<<endl;  
  11.  }  
  12.  //拷貝構造
  13.  CExample(const CExample& C)  
  14.  {  
  15.   a = C.a;  
  16.   cout<<"copy"<<endl;  
  17.  }  
  18.  //解構函式
  19.  ~CExample()  
  20.  {  
  21.   cout<< "delete: "<<a<<endl;  
  22.  }  
  23.      void Show ()  
  24.  {  
  25.          cout<<a<<endl;  
  26.      }  
  27. };  
  28. //全域性函式,傳入的是物件
  29. void g_Fun(CExample C)  
  30. {  
  31.  cout<<"test"<<endl;  
  32. }  
  33. int main()  
  34. {  
  35.  CExample test(1);  
  36.  //傳入物件
  37.  g_Fun(test);  
  38.  return 0;  
  39. }  

呼叫g_Fun()時,會產生以下幾個重要步驟:
(1).test物件傳入形參時,會先會產生一個臨時變數,就叫 C 吧。
(2).然後呼叫拷貝建構函式把test的值給C。 整個這兩個步驟有點像:CExample C(test);
(3).等g_Fun()執行完後, 析構掉 C 物件。
2. 物件以值傳遞的方式從函式返回
  1. class CExample   
  2. {  
  3. private:  
  4.  int a;  
  5. public:  
  6.  //建構函式
  7.  CExample(int b)  
  8.  {   
  9.   a = b;  
  10.  }  
  11.  //拷貝構造
  12.  CExample(const CExample& C)  
  13. 相關推薦

    學習kotlin第13天_具體化的型別引數內聯屬性宣告集合

    繼續之前的坑,我原本不打算繼續看文件了,直接上手個小專案,但是專案中遇見個小問題,list似乎和java中的有區別。。。一查文件發現在後面。。。所以繼續踩坑。 坑1、有時候我們需要型別作為引數傳給

    類的建構函式函式拷貝建構函式賦值函式

     類的四種基本預設函式:建構函式、解構函式、拷貝建構函式、賦值函式。 建構函式:建立類時,系統自動呼叫建構函式,用以初始化,分配空間,沒有自定義的建構函式時,系統預設一個無引數的建構函式。 class book { private:     int isBook;

    C++類中的一些細節(過載重寫覆蓋隱藏,建構函式函式拷貝建構函式賦值函式在繼承時的一些問題)

    1 函式的過載、重寫(重定義)、函式覆蓋及隱藏 其實函式過載與函式重寫、函式覆蓋和函式隱藏不是一個層面上的概念。前者是同一個類內,或者同一個函式作用域內,同名不同引數列表的函式之間的關係。而後三者是基類和派生類函式不同情況下的關係。 1.1 函式過載

    編寫類String的建構函式拷貝建構函式函式和賦值函式

    class String { public: String(const char *str = NULL); // 普通建構函式 String(const String &other); // 拷貝建構函式 ~String(void);

    編寫類String 的建構函式拷貝建構函式函式和賦值函式

     編寫類String 的建構函式、解構函式和賦值函式,已知類String 的原型為: class String { public:String(const char *str = NULL); // 普通建構函式String(const String &other

    讀書筆記:實現string類的建構函式拷貝建構函式函式過載運算子=

    #include <iostream> #include <cassert> #include <cstring> using namespace std; class MyString{ public: MyString(co

    建構函式函式拷貝建構函式

    一.建構函式 C++ 中類的建構函式與 java 很類似,其實對於面向物件程式設計來說,大傢伙都是一個思想,可能語法上有所不同而已。 class Student { public: // 建構函式 Student(){// 空引數建構函式

    編寫String類的普通建構函式拷貝建構函式函式賦值函式

    題目:編寫類String的建構函式、解構函式和賦值函式,已知類String的原型為: class String {  public:   String(const char *str = NULL); // 普通建構函式   String(const String

    類String的建構函式拷貝建構函式函式和賦值運算子過載函式的實現

    #include <iostream> using namespace std; class String { public: String(const char* str= NULL); String(const String& other); ~

    關於c++預設的建構函式函式拷貝建構函式move函式

    在c++中,當我們定義一個類的時候,如果我們什麼都不定義的時候,c++編譯器會預設的為我們生成一些函式。 例如定義一個Example類。 class Example{ }; 當我們定義一個Example類的時候,不定義任何操作的時候,c++編譯系統將為Example類生成如

    建構函式函式拷貝建構函式小結

            建構函式的定義與使用 建構函式是特殊的公有成員函式,其特徵如下: 1.函式名與類名相同。 2.建構函式無函式返回型別說明。注意是沒有而不是void,即什麼也不寫,也

    String類的建構函式函式拷貝建構函式賦值運算子過載

    面試碰到的題,答案來自網路搜尋。 class myString{ private: char* m_data; public: myString(const char *str=NULL); myString(const myString &other)

    找工作筆試面試那些事兒(5)---建構函式函式和賦值函式

    作者:寒小陽 時間:2013年9月。 出處:http://blog.csdn.net/han_xiaoyang/article/details/10833931。 宣告:版權所有,轉載請註明出處,謝謝。 類的建構函式、解構函式與賦值函式     &

    請為CMyString型別編寫建構函式copy建構函式函式和賦值運算子函式

    如下為型別CMyString的宣告,請為該型別編寫建構函式、copy建構函式、解構函式和賦值運算子函式。 1 class CMyString 2 { 3 public: 4 CMyString(const char* pData = nullptr); 5 CMyS

    類和物件——建構函式函式複製建構函式

    類: 要宣告類,用class,注意區分大小寫。類含有成員屬性和方法。在宣告類的末尾要加分號; 物件: 宣告完類之後,它並不能對程式產生任何影響。只有依據類,例項化物件,才可以訪問類成員屬性和方法。 下面是類例項化物件、動態分配記憶體與變數的對比: double pi=3.14; int* p

    【C++筆記】編寫類string的建構函式函式和賦值函式

    #include<iostream> using namespace std; class String { public: String(const char *str=NULL); //普通建構函式 String(const Stri

    建構函式函式和變數的生存期

    //referred from Wei Guo, Peking University #include<iostream> using namespace std; class Demo{ int id; public: Demo(int i)

    02.Solidity合約結構(初識別狀態變數區域性變數建構函式函式

    1.什麼是合約? 在區塊鏈上執行的程式,通常稱為智慧合約(Smart Contract,所以通常會把寫區塊鏈程式改稱寫智慧合約。 合約就是執行在區塊鏈上的一段程式 完整合約 pragma solidity ^0.4.4; contract Counter {

    C++中class類 的 建構函式函式

    說明: demo.cpp:main.cpp所在之處 Line.h:線段類的.h檔案 Line.cpp:線段類的.cpp檔案 Coordinate.h:座標類的.h檔案 Coordinate.cpp:

    c++單鏈表【建構函式運算子過載函式增刪查改等】

    c++中的單向連結串列寫法:實現增刪查改、建構函式、運算子過載、解構函式等。建立標頭檔案SList.h#pragma once typedef int DataType; //SList要訪問SListNode,可以通過友元函式實現,友元函式在被訪問的類中 class SL