2017-07-25 80 views
1

上下文:嵌入式編程和初始化列表細微差別,尤其是我認爲應該調用複製構造函數的細微差別。C++初始化指針/參考/複製細微差別

問題:在另一個類的初始值設定項列表中初始化一個值持有成員變量的類的實例化是否會調用複製構造函數? 下面提供了一個示例,其中TestClassCopy有一個由值保存的成員變量TestMember,而不是指針或引用。在提供的示例中,這個cppreference page似乎沒有充分說明這一點。

紅利問題:初始化程序列表中調用的複製構造函數是否會產生任何時間/空間性能影響?看起來像編譯器應該能夠優化,如果C++規範允許。


下面的代碼(生成與VS2015工具鏈測試):

TestMember.h(未示出TestMember.cpp空間原因)

#pragma once 

#include <stdint.h> 

class TestMember { 
public: 
    TestMember(uint8_t); 

private: 
    uint8_t m_value; 
}; 

TestClassCopy.h

#pragma once 

#include "test_member.h" 

class TestClassCopy { 
public: 
    TestClassCopy(); 
    virtual ~TestClassCopy(); 

private: 
    TestMember m_member; 
}; 

TestClassCopy.cpp

#include "test_class_copy.h" 

TestClassCopy::TestClassCopy() : 
    m_member(TestMember(255)) { // invokes copy constructor yes? 
} 

TestClassCopy::~TestClassCopy() { 
} 

爲了完整,其他的事情,我可能會做出假設我不應該:

對於初始化成員指針到TestMember,一個「新」列表和在析構函數中的'刪除'應該是足夠的。

對於成員引用,我的理解是,如果將引用傳遞給構造函數,您可以將其分配(因爲生命週期在初始化程序列表之外進行管理),因此存在更多細微差別。 但是,如果TestMember在初始化程序列表(在引用中)實例化,那麼這是一個禁止,因爲初始化完成後TestMember臨時消失。

TestMemberReference.h

#pragma once 

class TestMember; 

class TestClassReference { 
public: 
    TestClassReference(); 
    virtual ~TestClassReference(); 

private: 
    TestMember& m_member; 
}; 

TestMemberReference。CPP

#include "test_class_reference.h" 

#include "test_member.h" 

TestClassReference::TestClassReference() : 
    m_member(TestMember(255)) { // ew, don't do this; TestMember temporary will go out of scope 
} 

TestClassReference::~TestClassReference() { 
} 
+0

在你的第一個例子中,[copy is elided](https://stackoverflow.com/questions/12953127/what-are-copy-elision-and返回值優化),則不執行復制。 – CoryKramer

+0

你總是可以在複製構造函數 –

+0

@CoryKramer中放置打印語句或斷點,完美的是我一直在尋找的謝謝。我想這意味着你說'是的,複製構造函數可以被調用,但由於省略,它可能會或可能不會取決於編譯器優化設置等'。 PS。如果你想創建一個完整的答案,我可以接受它作爲答案。 – azydevelopment

回答

0

cppreference page似乎並不在於cppreference頁說提供

實施例充分地覆蓋該「初始化通過使用類或標識符direct initialization命名基部或構件」如果你點擊它,你可以閱讀,從C++ 17開始,

如果初始值設定項是一個prvalue表達式SE CV-非限定類型是相同的類爲T,初始化表達本身,而該臨時從它物化,用於初始化目標對象:看到複製省略

所以答案是:在C + +17沒有拷貝構造函數被調用。在C++ 17之前,技術上可以調用複製構造函數,但複製elision消除了該調用。你仍然可以觀察它,作爲證明,通過編寫你的例子g++ -fno-elide-constructors -O0 -std=c++14