初始化列表
在以前,初始化成員變量是通過這種方式來進(jìn)行的
struct Person {
int m_age;
int m_height;
Person(int age, int height) {
m_age = age;
m_height = height;
}
};
int main() {
Person person(18, 180);
getchar();
return 0;
}
通過定義一個(gè)構(gòu)造函數(shù),然后再創(chuàng)建對(duì)象時(shí)逞带,調(diào)用對(duì)應(yīng)的構(gòu)造函數(shù)時(shí)傳入?yún)?shù),在構(gòu)造函數(shù)內(nèi)部對(duì)成員變量進(jìn)行初始化纱新。初始化可以更便捷的方式來對(duì)成員變量進(jìn)行初始化展氓,初始化列表有以下特點(diǎn):
- 一種便捷的初始化成員了變量的方式
- 只能用在構(gòu)造函數(shù)中
- 初始化順序只跟成員了變量的聲明順序有關(guān)
初始化列表的格式如下:
struct Person {
int m_age;
int m_height;
Person(int age, int height) :m_age(age), m_height(height) {
}
};
int main() {
Person person(18, 180);
cout << person.m_age << endl;
cout << person.m_height << endl;
getchar();
return 0;
}
通過初始化列表的方式初始化成員變量與在構(gòu)造函數(shù)中的方式初始化成員是等價(jià)的。并且通過程序運(yùn)行的結(jié)果脸爱,也確實(shí)能達(dá)到與構(gòu)造函數(shù)中初始化成員變量的目的遇汞。
證明初始化列表與普通初始化方式等價(jià)
如果將本文中第一段代碼運(yùn)行起來,然后看生成的匯編代碼
通過生成的匯編代碼簿废,明顯看到空入,分別有對(duì)m_age與m_height賦值。
然后族檬,再將初始化列表初始化成員變量的方式運(yùn)行起來歪赢,然后看生成的匯編代碼
同樣的,在這一段匯編代碼中单料,同樣看到了有對(duì)m_age與m_height賦值埋凯,并且生成的匯編指令是一樣的。所以兩種寫法是完全等價(jià)的扫尖。對(duì)于初始化列表的這種方式递鹉,可以理解為是一種語法糖。
初始化列表中成員變量的初始化順序
如果現(xiàn)在將初始化列表進(jìn)行一些調(diào)整
struct Person {
int m_age;
int m_height;
Person(int age, int height) :m_age(m_height), m_height(height) {
}
};
int main() {
Person person(18, 180);
cout << person.m_age << endl;
cout << person.m_height << endl;
getchar();
return 0;
}
最終打印出來的結(jié)果m_age是一堆亂七八糟的值藏斩,說明m_age并沒有初始化躏结,而且,如果將初始化列表中的m_age,m_height賦值順序進(jìn)行調(diào)換狰域,也會(huì)出現(xiàn)一樣的情況媳拴,說明在通過初始化列表初始化成員變量時(shí)黄橘,與初始化列表的賦值順序無關(guān)。如果將成員變量的定義順序調(diào)換以下屈溉, 最終得到的結(jié)果是兩個(gè)成員變量都得到了初始化塞关,所以需要注意初始化列表成員變量初始化順序只與成員變量的定義順序有關(guān)
默認(rèn)參數(shù)與初始化列表的配合使用
利用前面的默認(rèn)參數(shù),與初始化列表結(jié)合的話子巾,會(huì)起到什么樣的效果呢帆赢?
struct Person {
int m_age;
int m_height;
Person(int age = 0, int height = 0) :m_age(age), m_height(height) {
}
};
int main() {
Person person1;
Person person2(17);
Person person3(17,170);
getchar();
return 0;
}
通過默認(rèn)參數(shù),就可以選擇在初始化的時(shí)候线梗,是否設(shè)置成員變量的初始值椰于,初始化對(duì)象時(shí),更加方便仪搔。
構(gòu)造函數(shù)的相互調(diào)用
有時(shí)候在編寫程序時(shí)瘾婿,有一種需求,在初始化對(duì)象時(shí)烤咧,需要將所有變量都初始化偏陪,但是有提供了多個(gè)構(gòu)造函數(shù),如果在每個(gè)構(gòu)造函數(shù)都將成員變量單獨(dú)初始化一遍的話煮嫌,就會(huì)導(dǎo)致很多重復(fù)的代碼笛谦,在這種情況下,就會(huì)考慮使用構(gòu)造函數(shù)來調(diào)用其他構(gòu)造函數(shù)初始化成員變量昌阿。
struct Person {
int m_age;
int m_height;
Person(){
}
Person(int age, int height) {
m_age = age;
m_height = height;
}
};
int main() {
Person person;
cout << person.m_age << endl;
cout << person.m_height << endl;
getchar();
return 0;
}
如果現(xiàn)在想要調(diào)用無參的構(gòu)造函數(shù)揪罕,并且最終創(chuàng)建出來對(duì)象的成員變量,都有初始值的話宝泵,你可能會(huì)想到在無參的構(gòu)造函數(shù)里面調(diào)用有參的構(gòu)造函數(shù)好啰,即將代碼修改為這樣
Person(){
Person(10,180);
}
如果這樣調(diào)用的話,你會(huì)發(fā)現(xiàn)最終在獲取創(chuàng)建出來對(duì)象的成員變量時(shí)儿奶,得到的值同樣是亂七八糟的框往,說明通過這種方式成員變量并沒有得到初始化。在構(gòu)造函數(shù)章節(jié)里面講到闯捎,構(gòu)造函數(shù)被調(diào)用椰弊,就標(biāo)志著一個(gè)新的對(duì)象被創(chuàng)建,說明這種方式是在無參構(gòu)造函數(shù)里面創(chuàng)建了一個(gè)新的對(duì)象瓤鼻,并且在無參構(gòu)造函數(shù)調(diào)用完畢后秉版,就銷毀了,對(duì)象的銷毀茬祷,也可以通過析構(gòu)函數(shù)得到證明清焕。那應(yīng)該怎樣初始化呢?根據(jù)C++語法的要求,在構(gòu)造函數(shù)相互調(diào)用時(shí)秸妥,只能構(gòu)造函數(shù)放到初始化列表當(dāng)中滚停,所以需要修改為下面這種形式
Person() :Person(10,180){
}
將構(gòu)造函數(shù)進(jìn)行修改以后,最終可以看到粥惧,成功的通過構(gòu)造函數(shù)調(diào)用了另外一個(gè)構(gòu)造函數(shù)键畴,并且成員變量也得到了初始化。
父類的構(gòu)造函數(shù)
假設(shè)現(xiàn)在有兩個(gè)類突雪,存在繼承關(guān)系
struct Person {
int m_age;
Person(){
cout << "Person::Person()" << endl;
}
Person(int age){
cout << "Person::Person()" << endl;
}
};
struct Student :Person {
int m_no;
Student() {
cout << "Student::Student()" << endl;
}
};
int main() {
Student student;
getchar();
return 0;
}
在創(chuàng)建子類兌現(xiàn)時(shí)起惕,構(gòu)造函數(shù)是如何調(diào)用的呢?將程序運(yùn)行起來以后咏删,看到的結(jié)果是先調(diào)用父類的構(gòu)造函數(shù)惹想,然后再調(diào)用當(dāng)前類的構(gòu)造函數(shù)。并且在默認(rèn)情況下饵婆,會(huì)調(diào)用父類無參的構(gòu)造函數(shù),但是戏售,如果子類的構(gòu)造函數(shù)顯式地調(diào)用了父類的有參構(gòu)造函數(shù)侨核,則就不會(huì)再去默認(rèn)調(diào)用父類的無參構(gòu)造函數(shù)」嘣郑可以通過初始化列表的方式來調(diào)用父類其他構(gòu)造函數(shù)
Student() :Person(10) {
cout << "Student::Student()" << endl;
}
關(guān)于這些結(jié)論搓译,都可以在程序運(yùn)行起來時(shí),通過匯編代碼來查看锋喜。
如果父類沒有無參的構(gòu)造函數(shù)些己,則需要在子類顯式的調(diào)用父類有參的構(gòu)造函數(shù),但是如果父類沒有構(gòu)造函數(shù)嘿般,則子類不用調(diào)用父類的構(gòu)造函數(shù)段标。
文章完。