c++析构函数可以使一个return-by-value的函数少执行一次拷贝构造函数,是什么原因?
PHPz
PHPz 2017-04-17 13:17:04
0
2
643
PHPz
PHPz

学习是最好的投资!

全部回覆(2)
刘奇

原因在於優化.
先來分析你的程式, a1是一個實例, a2是一個, getTest傳參是傳值那麼會有一個Temp1, getTest又有一個return Temp2.​​ 所以一共應該是四個對象.

但是, 編譯器會有優化, 甚至在你禁止優化的時候也會有一點點優化. 例如getTest的返回值, 本來按照語義是需要調用operator=, 實際上編譯器通常是直接調用CTest1(const CTest1&)這個建構子, 把兩次構造最佳化成1次.

你那個程式碼, 把析構函式裡面的cout註解掉, 就會發現只建構了3次. 因為析構函式裡面什麼都沒有的話, 編譯器開啟那個最佳化, 對你的程式碼功能上就沒有任何影響. 但是你開cout的話, 一旦優化掉的話, 程式碼的功能可能就不正確了.

你刪掉析構函式裡面的cout, 用gcc編譯, 加參數-O0 -fno-elide-constructors, 其實還是四個物件.

小葫芦
CTest1 getTestObj(CTest1 obj)
{
    return obj; /* copy */
}

int main()
{
    CTest1 a1; // construct             
    CTest1 a2 = /* copy */ getTestObj(a1/* copy */);
    return 0;
}

關於回傳值有一種對編譯器來說省事的方式,叫做回傳值最佳化(RVO - return value optimization)。編譯器會省略一步物件的COPY建構調用,不知道LZ用的什麼編譯器,在gcc(4.8.3)上面是預設開啟的,就是說結果是這樣的:

Constructor of CTest1:0
Copy constructor of CTest1:1
Copy constructor of CTest1:2
//如果去掉注释 就会打印下面三句话
 destroy id:1 
 destroy id:2
 destroy id:0
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!