c++構造函式

C++用以初始化對象的數據成員的一種函式。

基本介紹

  • 中文名C++構造函式
  • 外文名:C++ Constructor
構造函式作用,構造函式種類,淺拷與深拷貝,

構造函式作用

初始化對象的數據成員
規則:
構造函式與類同名且無返回值,在對象實例化時自動調用
構造函式可以有多個重載形式
實例化對象時僅用到一個構造函式
當用戶沒有定義構造函式時,編譯器自動生產一個構造函式
class School{public:    School()                  // 類School的構造函式    {      m_strName = "bullworth";    } private:    string m_strName;        // 數據成員}
該類對象被創建時,編譯系統對象分配記憶體空間,並自動調用該構造函式,由構造函式完成成員的初始化工作。
編譯系統為對象的每個數據成員(m_strName)分配記憶體空間,並調用構造函式School()自動地初始化對象的m_strName值設定為"bullworth"

構造函式種類

無參數構造函式
class Student { public:    Student()    {    m_strName= "luis";    m_iAge= 18;  } private:        string m_strName;    int m_iAge; }

1.如果創建一個類你沒有寫任何構造函式,則系統會自動生成默認的無參構造函式,函式為空,什麼都不做
2.只要你寫了一個下面的某一種構造函式,系統就不會再自動生成這樣一個默認的構造函式,如果希望有一個這樣的無參構造函式,則需要自己顯示地寫出來
一般構造函式(也稱重載構造函式)
Student(string _name, int _age){    m_strName=_name;    //將參數_name賦值給數據成員m_strName  m_iAge =_age;       //將參數_age賦值給數據成員m_iAge}
1.一般構造函式可以有各種參數形式,一個類可以有多個一般構造函式,函式名稱相同,參數可辨(c++重載函式要求),如你還可以寫一個 Sudent( int num)的構造函式
2.創建對象時根據傳入的參數不同調用不同的構造函式
拷貝構造函式(也稱複製構造函式)
定義方式:(const 類名 & 變數名)
  1. 拷貝構造函式參數為類對象本身的引用,用於將已存在對象的數據成員的值複製一份到新創建的對象中
  2. 若沒有顯式的拷貝構造函式,則系統會默認創建一個拷貝構造函式,但當類中有指針成員時,由系統默認創建該複製構造函式會存在風險,具體原因請參閱附錄1
  3. 拷貝構造函式調用時機:
    a.對象需要通過另外一個對象進行初始化
    b.對象以值傳遞的方式從函式返回
    c.對象以值傳遞的方式傳入函式參數
  4. 引用符號後的別名可省略
    例:
Student(const Student & s){    m_strName= s.m_strName;    // 將對象s中的數據成員值複製過來    m_iAge = s.m_iAge;} 
類型轉換構造函式
根據一個指定的類型的對象創建一個本類的對象
例如:下面將根據一個sting類型的對象創建了一個String對象
Student::Student(string _name){    m_strName=_name;       m_iAge =0;      }

下面使用上面定義的類對象來說明各個構造函式的用法:
int main(){    Student a,b;    // 調用了無參構造函式  Student c("Alan",18);    // 調用一般構造函式,數據成員初值被賦為指定值  Student c=Student ("Alan",18);    // 也可以使用該形式  a=c;    // 把c的數據成員的值賦值給a,而a已經事先被創建,不會調用任何構造函式  Student d("Jack");// 調用類型轉換構造函式  // 調用拷貝構造函式,有下面兩種調用方式  Student f(c);  Student e = c; //等號左邊的對象不是事先已經創建,故需要調用拷貝構造函式,參數為c}
將"Jack"創建為一個本類的臨時對象,然後調用等號運算符重載,將該臨時對象賦值給d

淺拷與深拷貝


上面提到,如果沒有自定義複製構造函式,則系統會創建默認的複製構造函式,但系統創建的默認複製構造函式只會執行“淺拷貝”,即將被拷貝對象的數據成員的 值一一賦值給新創建的對象,若該類的數據成員中有指針成員,則會使得新的對象的指針所指向的地址與被拷貝對象的指針所指向的地址相同,delete該指針 時則會導致兩次重複delete而出錯。下面是示例:
【淺拷貝與深拷貝】
#include <iostream> #include <string.h> using namespace std;class Person  { public :      Person(char * pN) // 構造函式     {         cout << "一般構造函式被調用 !\n";         m_pName = new char[strlen(pN) + 1]; //在堆中開闢一個記憶體塊存放pN所指的字元串         if(m_pName != NULL)  //如果m_pName不是空指針,則把形參指針pN所指的字元串複製給它         {             strcpy(m_pName ,pN);     } }  // 系統創建的默認複製構造函式,只做位模式拷貝     Person(Person & p)      {       m_pName = p.m_pName;  //使兩個字元串指針指向同一地址位置      }      ~Person( )     {         delete m_pName;     }  private :     char * m_pName; }; int main( ) {      Person man("lujun");     Person woman(man);  }
結果導致 man 和 woman 的指針都指向了同一個地址,函式結束析構時同一個地址被delete兩次。
下面自己設計複製構造函式,實現“深拷貝”,即不讓指針指向同一地址,而是重新申請一塊記憶體給新的對象的指針數據成員。
Person(Person & chs); {     m_pName=new char[strlen(p.m_pName)+ 1]; // 用運算符new為新對象的指針數據成員分配空間    if(m_pName)     {        strcpy(m_pName ,chs.m_pName); // 複製內容    }}
則新創建的對象的m_pName與原對象chs的m_pName不再指向同一地址了

相關詞條

熱門詞條

聯絡我們