原文地址:http://blog.csdn.net/yiyunoo/archive/2008/05/16/2452363.aspx
c++構(gòu)造函數(shù)后面的冒號(hào)
初始化列表,跟在{}里面的初始化沒(méi)有什么不同,但在非靜態(tài)const類型以及引用型成員變量必須在初始化列表里面初始化,不能在{}里面初始化.A(b)就是用父類的構(gòu)造函數(shù)進(jìn)行一部分初始化.
--------------
很多的人對(duì)中構(gòu)造函數(shù)寢初始化很多的困惑,對(duì)冒號(hào)后初始化不是太明白,總搞不清楚它們之間的區(qū)別,我想把我對(duì)這個(gè)問(wèn)題的理解和看法和大家討論討論。
在程序中定義變量并初始化的機(jī)制中,有兩種形式,一個(gè)是我們傳統(tǒng)的初始化的形式,即賦值運(yùn)算符賦值,還有一種是括號(hào)賦值,如:
int a=10;
char b='r';\\賦值運(yùn)算符賦值
int a(10);\
char b('r');\\括號(hào)賦值
以上定義并初始化的形式是正確的,可以通過(guò)編譯,但括號(hào)賦值只能在變量定義并初始化中,不能用在變量定義后再賦值,這是和賦值運(yùn)算符賦值的不同之處,如:
(1)
int a; \\先定義一個(gè)變量
......
a=10; \\根據(jù)需要賦值
(2)
int b; \\先定義一個(gè)變量
......
b(10); \\和(1)一樣根據(jù)需要賦值
(1)是可以用通過(guò)編譯,定義一個(gè)變量a但并沒(méi)有初始化,在需要變量a的時(shí)候,通過(guò)賦值運(yùn)算符把10賦給a,而在(2)中,是通過(guò)括號(hào)把10賦值給b,但編譯系統(tǒng)認(rèn)為
這是一個(gè)函數(shù)的調(diào)用,函數(shù)名為b,10為實(shí)際參數(shù),所以編譯錯(cuò)誤。因此,括號(hào)賦值只用在定義變量并初始化中。
現(xiàn)在我們來(lái)看構(gòu)造函數(shù)中冒號(hào)初始化和函數(shù)初始化的問(wèn)題,類構(gòu)造函數(shù)的作用是創(chuàng)建一個(gè)類的對(duì)象時(shí),調(diào)用它來(lái)構(gòu)造這個(gè)類對(duì)象的數(shù)據(jù)成員,一要給出此數(shù)據(jù)成員分配內(nèi)存空間,二是要給函數(shù)數(shù)據(jù)成員初始化,構(gòu)造數(shù)據(jù)成員是按數(shù)據(jù)成員在類中聲明的順序進(jìn)行構(gòu)造。
冒號(hào)初始化與函數(shù)體初始化的區(qū)別在于:
冒號(hào)初始化是給數(shù)據(jù)成員分配內(nèi)存空間時(shí)就進(jìn)行初始化,就是說(shuō)分配一個(gè)數(shù)據(jù)成員只要冒號(hào)后有此數(shù)據(jù)成員的賦值表達(dá)式(此表達(dá)式必須是括號(hào)賦值表達(dá)式),那么分配了內(nèi)存空間后在進(jìn)入函數(shù)體之前給數(shù)據(jù)成員賦值,就是說(shuō)初始化這個(gè)數(shù)據(jù)成員此時(shí)函數(shù)體還未執(zhí)行。
對(duì)于在函數(shù)中初始化,是在所有的數(shù)據(jù)成員被分配內(nèi)存空間后才進(jìn)行的。
這樣是有好處的,有的數(shù)據(jù)成員需要在構(gòu)造函數(shù)調(diào)入之后函數(shù)體執(zhí)行之前就進(jìn)行初始化如引用數(shù)據(jù)成員,常量數(shù)據(jù)成員和對(duì)象數(shù)據(jù)成員,看下面的一段程序:
class student
{public :
student ()
.
.
.
protected:
const int a;
int &b;
}
student ::student (int i,int j)
{
a=i;
b=j;
}
在Student類中有兩個(gè)數(shù)據(jù)成員,一個(gè)是常量數(shù)據(jù)成員,一個(gè)是引用數(shù)據(jù)成員,并且在構(gòu)造函數(shù)中初始化了這兩個(gè)數(shù)據(jù)成員,但是這并不能通過(guò)編譯,因?yàn)槌A砍跏蓟瘯r(shí)必須賦值,它的值是不能再改變的,與常量一樣引用初始化也需要賦值,定義了引用后,它就和引用的目標(biāo)維系在了一起,也是不能再被賦值的。所以C ++":"后初始化的機(jī)制,使引用和常量數(shù)據(jù)成員變?yōu)榭赡艿模琒tudent類的構(gòu)造函數(shù)應(yīng)為:
student ::student(int i,int j):a(i),b(j){}
在下面的程序:
class teach
{
public :
teach(char *p="name",int a=0)
. .
.
protected:
char name[30];
int age;
}
teach ::teach(char*p,int a)
{
strcopy(name ,p);
age=a;
cout>>name>>endl;
}
class student
{
public:
student (char *p="name");
.
.
.
protected;
char name[30];
teach teacher;
};
student::student(char *p)
{
strcopy(name,p);
cont>>name>>endl;
}
在上面的程序中通不過(guò)編譯,編譯系統(tǒng)會(huì)告訴你teacher這個(gè)類對(duì)象缺默認(rèn)構(gòu)造函數(shù),因?yàn)樵趖each 類中沒(méi)有定義默認(rèn)的構(gòu)造函數(shù)。那么帶參數(shù)的構(gòu)造函數(shù)怎么進(jìn)行構(gòu)造呢?通過(guò)我們前面提到的冒號(hào)賦值。那它的構(gòu)造函數(shù)應(yīng)該是:
student::student(char *p,char *pl,int ag):teacher(pl,ag)
{
strcopy(name,p);
cont>>name>>endl;
}
就是說(shuō)在沒(méi)有默認(rèn)構(gòu)造函數(shù)的時(shí)候,如果一個(gè)類對(duì)象是另一個(gè)類的數(shù)據(jù)成員,那么初始化這個(gè)數(shù)據(jù)成員,就應(yīng)該放到冒號(hào)后面。這樣可以帶參數(shù)。在類的定義中,如:
protected;
char name[30];
teach teacher
類對(duì)象是不能帶參數(shù)的,因?yàn)樗皇锹暶鳌?
所以在C++中就增加了這種機(jī)制,這是面向?qū)ο缶幊趟仨毜摹2恢牢抑v明白沒(méi)有。如不明白請(qǐng)查閱有關(guān)資料