我們在程序中不可避免的會遇到臨時變量,那么在 C++ 中也會不可避免的會遇到臨時對象。我們以代碼為例來進行分析
創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供和布克賽爾蒙古網(wǎng)站建設、和布克賽爾蒙古做網(wǎng)站、和布克賽爾蒙古網(wǎng)站設計、和布克賽爾蒙古網(wǎng)站制作等企業(yè)網(wǎng)站建設、網(wǎng)頁設計與制作、和布克賽爾蒙古企業(yè)網(wǎng)站模板建站服務,10余年和布克賽爾蒙古做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡服務。#includeclass 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; }
我們這段代碼是想要在 Test() 中以 0 作為參數(shù)調(diào)用 Test(int i),然后將成員變量 mi 初始化為 0,最后想要打印它的值。我們來看看編譯結果
我們看到打印的是一個隨機數(shù),并不是我們所期望的 0。那這到底是怎么回事呢?那么我們想下:構造函數(shù)既然是一個特殊的函數(shù)。那么它是否可以直接調(diào)用呢?是否可以在構造函數(shù)中調(diào)用構造函數(shù)呢?直接調(diào)用構造函數(shù)的行為是什么?我們就直接說答案了。直接調(diào)用構造函數(shù)將產(chǎn)生一個臨時對象,臨時對象的生命周期只有一條語句的時間,臨時對象的作用域只在一條語句中,臨時對象是 C++ 中值得警惕的灰色地帶!上面那個程序也就是說第 15 行的調(diào)用的構造函數(shù)會產(chǎn)生臨時對象,它的生命周期只有那一行的時間,所以在后面我們打印出來的才會是一個隨機值。
下面我們在上面程序的基礎上進行修改,代碼如下
#includeclass Test { private: int mi; void init(int i) { mi = i; } public: Test() { init(0); } void print() { printf("mi = %d\n", mi); } }; int main() { Test t; t.print(); return 0; }
我們再次編譯看看結果
這次我們看到它按照我們所想要的初始化為 0 了。現(xiàn)代的 C++ 編譯器在不影響最終執(zhí)行結果的前提下,會盡力減少臨時對象的產(chǎn)生?。?!
我們再來看一個示例代碼
#includeclass Test { private: int mi; public: Test(int i) { mi = i; printf("Test(int i): %d\n", mi); } Test(const Test& obj) { mi = obj.mi; printf("Test(const Test& obj): %d\n", mi); } Test() { mi = 0; printf("Test()\n"); } void print() { printf("mi = %d\n", mi); } ~Test() { printf("~Test()\n"); } }; Test func() { return Test(50); } int main() { Test t = Test(10); Test tt = func(); t.print(); tt.print(); return 0; }
我們看到在第 40 行定義了 Test 對象 t,并將它初始化為 10。按照我們想的它在這塊先是生成一個臨時對象初始化為 10 并將這個臨時對象賦值給對象 t。所以這塊可能會牽扯到拷貝構造函數(shù)。第 41 行也是這樣的,先是在 func 函數(shù)中生成一個臨時對象 Test(50),并將它賦值給對象 tt。所以也會牽扯到拷貝構造函數(shù)。那么我們來編譯下看看結果
我們看到并沒有打印出拷貝構造函數(shù)的身影。再回想下我們之前講的,現(xiàn)代編譯器已經(jīng)大大優(yōu)化了,盡量會避免臨時對象的產(chǎn)生。那么第 40 行將會等價于 Test t(10),第 41 行將會等價于 Test tt = Test(50) ==> Test tt(50);所以這樣也就能解釋清楚了,它確實沒牽扯到拷貝構造函數(shù)。我們得隨時注意 C++ 中的臨時對象,因為它將會導致一些莫名其妙的結果。通過對臨時對象的學習,總結如下:1、直接調(diào)用構造函數(shù)將產(chǎn)生一個臨時對象,臨時對象是性能的瓶頸,也是 bug 的來源之一;2、現(xiàn)代 C++ 編譯器會盡力避開臨時對象,實際工程開發(fā)中需要人為的避開臨時對象。
歡迎大家一起來學習 C++ 語言,可以加我QQ:243343083。
另外有需要云服務器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。