總結(jié)
- 初始化值的是創(chuàng)建變量時(shí)賦予變量一個(gè)值(不同于賦值的概念)
- 使用等號(hào)
=
初始化對(duì)象時(shí)是拷貝初始化妙同,否則是直接初始化 - 直接初始化也可能調(diào)用拷貝構(gòu)造函數(shù)晃酒,拷貝初始化可以不調(diào)用拷貝構(gòu)造函數(shù)
初始化概念
對(duì)象是類的實(shí)例化,在內(nèi)存中會(huì)占據(jù)一個(gè)一定大小的空間。創(chuàng)建一個(gè)對(duì)象分為兩步:分配內(nèi)存空間和初始化,剛剛分配的空間有可能包含臟數(shù)據(jù)检痰,因此我們需要通過(guò)初始化函數(shù)(C++中指的是構(gòu)造函數(shù))對(duì)分配的空間進(jìn)行正確地初始化以保證對(duì)象值的合法性。
初始化指的就是創(chuàng)建變量是賦予它一個(gè)值(不同于賦值的概念)锨推,類的構(gòu)造函數(shù)控制其對(duì)象的初始化過(guò)程铅歼,無(wú)論何時(shí)只要類的對(duì)象被創(chuàng)建就會(huì)執(zhí)行構(gòu)造函數(shù)。
拷貝初始化與直接初始化
C++由于歷史原因包含多種不同的初始化方式爱态,我們可以簡(jiǎn)單地認(rèn)為:如果使用等號(hào)=
初始化變量則執(zhí)行的是拷貝初始化(編譯器將等號(hào)右邊的對(duì)象值拷貝到新創(chuàng)建的對(duì)象中去)谭贪,不使用等號(hào)時(shí)使用的是直接初始化。
string s1 = "tomocat"; // 拷貝初始化
string s2("tomocat"); // 直接初始化
string s3(10, 'c'); // 直接初始化, s3內(nèi)容為cccccccccc
// s4拷貝初始化
string s4 = string(10, 'c');
// 等價(jià)于
string temp = string(10, 'c');
string s4 = temp;
注意當(dāng)我們使用直接初始化時(shí)(不用等號(hào)=
初始化變量)锦担,實(shí)際上是要求編譯器使用普通的函數(shù)匹配來(lái)選擇與我們提供的參數(shù)最匹配的構(gòu)造函數(shù)(當(dāng)然也包括拷貝構(gòu)造函數(shù))俭识,當(dāng)我們使用拷貝初始化時(shí)(使用=
初始化變量),我們要求編譯器將右側(cè)運(yùn)算對(duì)象的值拷貝到正在創(chuàng)建的對(duì)象中洞渔,如果有需要的話還需要進(jìn)行類型轉(zhuǎn)換套媚。
實(shí)戰(zhàn)
盡管直接初始化和拷貝初始化的定義如上所示缚态,但是由于直接初始化可能調(diào)用拷貝構(gòu)造函數(shù),拷貝初始化不一定調(diào)用拷貝構(gòu)造函數(shù)堤瘤,我們還是結(jié)合一些實(shí)例來(lái)看一下玫芦。我們定義如下的結(jié)構(gòu)體:
struct Cat {
// 默認(rèn)構(gòu)造函數(shù)
Cat() {
printf("Cat()\n");
}
// 析構(gòu)函數(shù)
~Cat() {
printf("~Cat()\n");
}
// 構(gòu)造函數(shù)
Cat(const Cat &cat) {
printf("Cat(const Cat &cat)\n");
}
// 接受string對(duì)象的構(gòu)造函數(shù)
Cat(std::string n) : name(n) {
printf("Cat(std::string n)\n");
}
// 拷貝賦值運(yùn)算符
Cat& operator=(const Cat &cat) {
printf("Cat& operator=(const Cat &cat)\n");
return *this;
}
std::string name;
};
幾種常用的初始化實(shí)現(xiàn)方式如下:
int main(void) {
// 拷貝初始化: 執(zhí)行std::string到Cat的隱式類型轉(zhuǎn)換
Cat cat1 = std::string("tomo");
printf("-------------------------------------------------------------------\n");
// 拷貝初始化: 調(diào)用拷貝構(gòu)造函數(shù)而不是拷貝賦值運(yùn)算符(因?yàn)檫@里是初始化而不是賦值)
Cat cat2 = cat1;
printf("-------------------------------------------------------------------\n");
// 直接初始化: 調(diào)用拷貝構(gòu)造函數(shù)
Cat cat3(cat2);
printf("-------------------------------------------------------------------\n");
return 0;
}
輸出信息如下:
Cat(std::string n)
-------------------------------------------------------------------
Cat(const Cat &cat)
-------------------------------------------------------------------
Cat(const Cat &cat)
-------------------------------------------------------------------
~Cat()
~Cat()
~Cat()
Reference
[1] https://blog.csdn.net/sirenxiaohuayuan/article/details/90142419