C++用以初始化對象的數據成員的一種函式。
基本介紹
- 中文名:C++構造函式
- 外文名:C++ Constructor
構造函式作用
class School{public: School() // 類School的構造函式 { m_strName = "bullworth"; } private: string m_strName; // 數據成員}
構造函式種類
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}
2.創建對象時根據傳入的參數不同調用不同的構造函式
- 拷貝構造函式參數為類對象本身的引用,用於將已存在對象的數據成員的值複製一份到新創建的對象中
- 拷貝構造函式調用時機:
a.對象需要通過另外一個對象進行初始化
b.對象以值傳遞的方式從函式返回
c.對象以值傳遞的方式傳入函式參數 - 引用符號後的別名可省略
例:
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}
淺拷與深拷貝
上面提到,如果沒有自定義複製構造函式,則系統會創建默認的複製構造函式,但系統創建的默認複製構造函式只會執行“淺拷貝”,即將被拷貝對象的數據成員的 值一一賦值給新創建的對象,若該類的數據成員中有指針成員,則會使得新的對象的指針所指向的地址與被拷貝對象的指針所指向的地址相同,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); }
Person(Person & chs); { m_pName=new char[strlen(p.m_pName)+ 1]; // 用運算符new為新對象的指針數據成員分配空間 if(m_pName) { strcpy(m_pName ,chs.m_pName); // 複製內容 }}