2012-01-13 333 views
1

我正在做對嗎?這是我的代碼高度簡化的版本:在初始化列表中初始化引用對象成員

class Logger { 
    public: 
     Logger(std::ostream) { /*...*/} 
}; 

class Driver { 
public: 
    Driver() : m_logger(std::cout) {} 
    Driver(Logger& logger) : m_logger(logger) {} 
private 
    Logger m_logger; 
}; 

所以我Driver類有Logger類型的成員。當我調用無參數構造函數Driver()時,Driver的實例使用std::cout創建它自己的Logger實例。

當調用Driver(Logger)時,實例應使用作爲參考傳遞的已存在的Logger實例。

上面的代碼使用g ++編譯。雖然我明白撥打Driver()會發生什麼情況,但撥打Driver(Logger)時我不會收到什麼結果。 Logger沒有構造函數,它接受Logger作爲參數(「複製構造函數」)的引用。那麼撥打Driver(Logger)時執行什麼?

+0

你自己的'Driver'提供一個構造函數接收'Logger'參考:'驅動器(記錄器和採集器)' ,這是初始化參考成員的標準和常用方式。我不明白這個問題。 – 2012-01-13 11:09:31

+0

你不「叫」構造函數。永遠。 – 2012-01-13 11:10:53

+1

順便說一句,你不能複製流。 – 2012-01-13 11:11:21

回答

2

Logger的簡單複製構造函數爲您合成,除非您自己聲明一個構造函數。

這與您如何爲您合成簡單的默認構造函數(如果您未聲明默認的用戶定義的構造函數)大致相同。


[C++11: 12.8/7]:如果類定義不明確聲明拷貝構造函數,一個是隱式聲明。如果類定義聲明移動構造函數或移動賦值運算符,則隱式聲明的複製構造函數 被定義爲已刪除;否則,它被定義爲默認(8.4)。如果類具有用戶聲明的複製賦值運算符或用戶聲明的析構函數,則不推薦使用後一種情況。因此,對於類定義

struct X { 
    X(const X&, int); 
}; 

複製構造函數是隱式聲明的。如果用戶聲明的構造將在後面定義爲

X::X(const X& x, int i =0) { /* ... */ } 

然後任何使用X的拷貝構造是形成不良的,因爲模糊的;不需要診斷。

[C++11: 12.8/8]:一類的隱式聲明的拷貝構造函數X將有形式

X::X(const X&) 

如果

  • 每個直接或虛基類BX有交流OPY構造,其第一個參數是const B&型或const volatile B&的,和
  • X屬於類型M(或其陣列)的所有非靜態數據成員,每個這樣的類型具有複製構造,其第一參數類型爲const M&const volatile M&

否則,隱式聲明的拷貝構造函數都會有形式

X::X(X&) 
2

當你構建一個DriverLogger的說法,它採取的是參考和複製Logger構造函數被調用來初始化m_logger,所以你最終得到一個新的Logger是爭論的一個副本。複製構造函數由編譯器提供,除非通過聲明覆制構造函數private明確地使Logger不可複製。

似乎完全有效,除了你應該使logger參數const參考;畢竟,你會複製它,而不是修改它。

+0

什麼複製構造函數?我還沒有定義'Logger'的複製構造函數。或者這是隱式完成的? – MBober 2012-01-13 11:09:43

+0

@MBober:如果沒有明確定義,編譯器會插入默認的拷貝構造函數。 – 2012-01-13 11:12:00