前言
對一個類而言,構造函數恐怕是最重要的一個成員函數了。關於構造函數的細節繁多,並且隨著新標准的提出,構造函數有了新的特性。本文來集中探討下構造函數的那些鮮為人知的一面。
構造函數
構造函數的作用眾所周知:在類的對象被創建時,控制對象的初始化和賦值。
構造函數的一般形式:
類名(arg_list);
其中arg_list是用逗號隔開的參數列表。
特點:無返回值類型,且不可加const限制。
默認構造函數
需要特別指出,無參的構造函數是默認的,有參但都有默認參數的構造函數也是默認構造。
------------------------------分割線------------------------------
C++ Primer Plus 第6版 中文版 清晰有書簽PDF+源代碼 http://www.linuxidc.com/Linux/2014-05/101227.htm
讀C++ Primer 之構造函數陷阱 http://www.linuxidc.com/Linux/2011-08/40176.htm
讀C++ Primer 之智能指針 http://www.linuxidc.com/Linux/2011-08/40177.htm
讀C++ Primer 之句柄類 http://www.linuxidc.com/Linux/2011-08/40175.htm
將C語言梳理一下,分布在以下10個章節中:
舉例證明:
#include <iostream>
using namespace std;
class MyClass
{
protected:
int a = 0;
int b{1};
public:
MyClass(int a = 0, int b = 0):a(a), b(b) //有默認實參的構造方法就是默認構造
{
cout << "MyClass(int a = 0, int b = 0)" << endl;
}
int getA()const
{
return a;
}
int getB()const
{
return b;
}
};
int main()
{
MyClass my; //調用默認構造
cout << "a = " << my.getA() << ends << "b = " << my.getB() << endl;
cin.get();
return 0;
}
運行
從運行結果,即可驗證結論。有參但都有默認參數的構造函數也是默認構造,這一點恐怕是很多人都容易忽略的、
默認構造初始化類的數據成員的規則:
如果存在類內的初始值,用它來初始化成員。
否則,默認初始化。(這個規則雖是標准,但大多數編譯器還做不到)
幾個概念
1.類內初始值。
在上例代碼中,int a = 0; int b{1};這種形式就是類內初始值。後面會說明何時使用類內初始值。
2.默認初始化。
內置類型,如int,double類型等。int->0,double->0.0。就是默認初始化。
類類型,使用該類的默認構造初始化,就是默認初始化。
默認構造並不是總是存在的,若有另一個構造函數(非默認構造)存在,則編譯器並不會提供一個無參的默認構造。新標准提出了一種方式:如 MyClass() = default; 關鍵字 default 的這種使用,表明要求編譯器生成一個默認的構造函數。
3.初始值列表
構造函數 MyClass(int a = 0, int b = 0):a(a), b(b){...} 其中 a(a), b(b)就是初始值列表。
4.什麼是初始化?什麼是賦值?
對象在內存中創建(有了內存實體),第一次有的值,叫做初始化。把原先的值覆蓋掉,叫做賦值。
一般情況下,構造函數在初始值列表中完成初始化,在函數體中完成賦值。
這個結論並不好證明,但還是有辦法的,辦法就是借助:const類型和引用類型。如下代碼:
#include <iostream>
using namespace std;
class MyClass
{
protected:
int a = 0;
const int ca = 0;
int& ra;
public:
MyClass(int a) :a(a), ca(a), ra(this->a){}
int getA()const
{
return a;
}
void printCa()const
{
cout << "ca = " << ca << endl;
}
void printRa()const
{
cout << "ra = " << ra << endl;
}
};
int main()
{
MyClass my(1);
cout << my.getA() << endl;
my.printCa();
my.printRa();
cin.get();
return 0;
}
運行
const類型和引用類型,在創建時,必須進行初始化。若是把 ca = a; ra = this->a; 移到構造函數體內部,則無法通過編譯。也就是說,一旦進入構造函數體,初始化就已經完成了。
需要指出,初始值列表的順序並不代表著實際初始變量的順序,而成員的聲明順序才是。
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2015-02/113672p2.htm