構造函數是特殊的成員函數,只要創建類類型的新對象,都要執行構造函數,構造函數的工作是保證每個對象的數據成員具有合適的初值
本文地址:http://www.cnblogs.com/archimedes/p/cpp-constructor.html,轉載請注明源地址
C++采用構造函數為對象初始化:
功能:初始化對象
函數名:與類名相同
參數:無
返回值:不指定返回值(不能寫void )
位置:通常作為public成員
內容:任意,通常只包含成員賦值語句
調用方法:通常創建對象時自動調用
Time time; Time time = Time();//OK
C++中的構造函數主要分為四類:
無參構造函數、有參構造函數、構造函數與參數初始化列表、默認構造函數、
注意:
在實例化對象時自動調用 對象名後不能含有括號"類名 對象名( )" 在構造函數中不僅可以對數據成員賦初值,也可以包含其他語句(不提倡加入與初始化無關的語句)#include<iostream> using namespace std; class Time { public: Time(); void display() const; private: int m_iHour; int m_iMinute; int m_iSec; }; Time::Time() { m_iHour = 0; m_iMinute = 0; m_iSec = 0; } void Time::display()const { cout << m_iHour << ":" << m_iMinute << ":" << m_iSec << endl; } int main() { Time time; time.display(); Time obj = Time(); obj.display(); Time *p = new Time; p->display(); delete p; p = NULL;return 0; }
#include<iostream> using namespace std; class Time { public: Time(int aHour, int aMinute, int aSec); void display() const; private: int m_iHour; int m_iMinute; int m_iSec; }; Time::Time(int aHour, int aMinute, int aSec) { m_iHour = aHour; m_iMinute = aMinute; m_iSec = aSec; } void Time::display()const { cout << m_iHour << ":" << m_iMinute << ":" << m_iSec << endl; } int main() { Time time(12,30,20); time.display(); time = Time(0,0,0); time.display(); Time *p = new Time(1,2,3); p->display(); delete p; p = NULL;return 0; }
由於構造函數可含有參數,因此構造函數可以重載
#include<iostream> using namespace std; class Time { public: Time(); Time(int aHour, int aMinute, int aSec); void display() const; private: int m_iHour; int m_iMinute; int m_iSec; }; Time::Time() { m_iHour = 0; m_iMinute = 0; m_iSec = 0; } Time::Time(int aHour, int aMinute, int aSec) { m_iHour = aHour; m_iMinute = aMinute; m_iSec = aSec; } void Time::display()const { cout << m_iHour << ":" << m_iMinute << ":" << m_iSec << endl; } int main() { Time time; time.display(); Time Time(12,30,20); Time.display(); system("pause"); return 0; }重載構造函數時一定要防止產生二義性。
Time(); //聲明無參構造函數Time(int ,int); //有兩個參數的構造函數 Time(int ,int = 10, int=10);//有一個參數不是默認參數… … Time time1; Time time2(15); //調用第三個Time time3(15,30); //Error,調用第二個還是第三個?
Time::Time(int aHour, int aMinute, int aSec):m_iHour(aHour),m_iMinute(aMinute),m_iSec(aSec){}
注意:
const成員、引用成員及子對象成員必須使用初始化列表初始化class ConstRef { public: ConstRef(int aVal); private: int m_iVal; const int m_ci; int &m_r; }; ConstRef::ConstRef(int aVal):m_ival(aVal) { m_ci = aVal; //Error m_r = m_iVal; //Error }
初始化列表只在實現時出現;
class ConstRef { public: ConstRef(int aVal); private: int m_iVal; const int m_ci; int &m_r; }; ConstRef::ConstRef(int aVal):m_iVal(aVal), m_ci(aVal), m_r(m_iVal){} int main() { ConstRef obj(4); return 0; }
構造函數初始化列表不能指定初始化次序
class Point { public: Point(int aVal):m_iY(aVal), m_iX(m_iY){} //Error private: int m_iX; int m_iY; };
按照成員聲明的順序編寫構造函數初始化列表。盡量避免使用成員初始化成員。
class Point { public: Point(int aVal):m_iX(aVal), m_iY(m_iX){} private: int m_iX; int m_iY; };
概念:初始化對象時不提供參數時所調用的構造函數
int main() { Time time1; Time time2(); //error Time &r = *new Time; delete Time; return 0; }
自定義的構造函數、由系統創建的構造函數、含默認參數的構造函數
自定義的構造函數:
#include<iostream> using namespace std; class Time { public: Time(); void display() const; private: int m_iHour; int m_iMinute; int m_iSec; }; Time::Time() { m_iHour = 0; m_iMinute = 0; m_iSec = 0; } void Time::display()const { cout << m_iHour << ":" << m_iMinute << ":" << m_iSec << endl; } int main() { Time time; time.display(); Time obj = Time(); obj.display(); Time *p = new Time; p->display(); delete p; p = NULL; system("pause"); return 0; }
自定義的構造函數:
類體中若沒有構造函數,則系統會生成一個默認構造函數。
#include<iostream> using namespace std; class Time { public: void display() const; private: int m_iHour; int m_iMinute; int m_iSec; }; void Time::display()const { cout << m_iHour << ":" << m_iMinute << ":" << m_iSec << endl; } int main() { Time time; time.display(); system("pause"); return 0; }
類體中若含有構造函數則系統不會生成默認構造函數;系統創建的默認構造函數就是函數體為空的無參構造函數Time::Time( ){}
含默認參數的構造函數:
#include<iostream> using namespace std; class Time { public: Time(int aHour=0, int aMinute=0, int aSec=0); void display() const; private: int m_iHour; int m_iMinute; int m_iSec; }; Time::Time(int aHour, int aMinute, int aSec) { m_iHour = aHour; m_iMinute = aMinute; m_iSec = aSec; } void Time::display()const { cout << m_iHour << ":" << m_iMinute << ":" << m_iSec << endl; } int main() { Time time1; time1.display(); Time time2(12,30,20); time2.display(); system("pause"); return 0; }
說明:
在聲明構造函數時,形參名可以省略(不推薦)
Time(int = 10,int =10,int =10);
一個類只能有一個默認構造函數
Time
(); //聲明無參構造函數
Time
(int aX=10,int aY=10,int aZ=10);
Time box1; //ERROR
推薦使用默認參數的默認構造函數,以提高代碼重用。
一個類中只能含有一個默認構造函數
構造函數的函數名與類名相同,不寫返回值,因而不能指定包括void在內的任何返回值類型。
構造函數通常為public
構造函數是成員函數,它可在類體內或類體外實現。
構造函數可以重載,重載時防止產生“二義性”。
最好用參數初始化列表實現構造函數
類外實現構造函數時初始化列表在實現時出現!
無參構造函數和全部參數都含有默認值的構造函數都是默認構造函數
一個類只能含有一個默認構造函數
習慣上要求定義一個含默認參數的默認構造函數,以增強類的通用性