0. 問(wèn)題:下面的程序輸出什么襟士?為什么哩盲?
#include <stdio.h>
class Test
{
private:
int mi;
public:
Test(int i)
{
mi = i;
}
Test()
{
Test(0);
}
void print()
{
printf("mi = %d\n", mi);
}
};
int main()
{
Test t;
t.print();
return 0;
}
輸出結(jié)果:
mi = -1216962560
- 程序意圖:在Test()中以0作為參數(shù)調(diào)用Test(int i), 將成員變量mi的初始值值為0柿赊。
- 運(yùn)行結(jié)果:成員變量mi的值為隨機(jī)值嫂丙。
為什么會(huì)這樣?憾儒?询兴?
1. 思考:構(gòu)造函數(shù)是一個(gè)特殊函數(shù),因此:
- 是否可以直接調(diào)用起趾? ——可以(構(gòu)造函數(shù)可以自動(dòng)調(diào)用和手動(dòng)調(diào)用)
- 是否可以在構(gòu)造函數(shù)中調(diào)用構(gòu)造函數(shù)诗舰?——(編譯器編譯可以通過(guò))
- 直接調(diào)用構(gòu)造函數(shù)的行為是什么?后果是什么训裆?
答案:
- 直接調(diào)用構(gòu)造函數(shù)將產(chǎn)生一個(gè)臨時(shí)對(duì)象
- 臨時(shí)對(duì)象的生命周期只有一條語(yǔ)句的時(shí)間眶根,過(guò)了這一條語(yǔ)句的時(shí)間,臨時(shí)對(duì)象自動(dòng)被析構(gòu)函數(shù)析構(gòu)而不復(fù)存在
- 臨時(shí)對(duì)象的作用域只在一條語(yǔ)句中
- 臨時(shí)對(duì)象是C++中值得警惕的灰色地帶
編程說(shuō)明:去掉臨時(shí)變量
#include <stdio.h>
class Test
{
private:
int mi;
void init(int i) // 添加init(int i)初始設(shè)置函數(shù)
{
mi = i;
}
public:
Test(int i)
{
init(i);
}
Test()
{
init(0);
}
void print()
{
printf("mi = %d\n", mi);
}
};
int main()
{
Test t;
t.print();
return 0;
}
輸出結(jié)果:
mi = 0
2. 編譯器的行為
現(xiàn)代C++編譯器在不影響最終執(zhí)行結(jié)果的前提下缭保,會(huì)盡力減少臨時(shí)對(duì)象的產(chǎn)生!r琛艺骂!
3. 小結(jié)
- 直接調(diào)用構(gòu)造函數(shù)將會(huì)產(chǎn)生一個(gè)臨時(shí)對(duì)象
- 臨時(shí)對(duì)象是性能的瓶頸,也是bug的來(lái)源之一
- 現(xiàn)代C++編譯器會(huì)盡力避開(kāi)臨時(shí)對(duì)象
- 實(shí)際工程開(kāi)發(fā)中需要人為的避開(kāi)臨時(shí)對(duì)象隆夯,因此钳恕,在寫代碼和在設(shè)計(jì)上要有意識(shí)的避開(kāi)臨時(shí)對(duì)象