2012-02-08 54 views
9

在的Deitel C++書( 「C++ 11爲程序員」,p.286),存在的一個示例:爲什麼通過引用傳遞涉及拷貝構造函數?

class Date { ... } 

class Employee { 
public: 
    Employee(const string &, const string &, const Date &, const Date &); 
private: 
    string firstName; 
    string lastName; 
    const Date birthDate; 
    const Date hireDate; 
} 

Employee::Employee(const string &first, const string &last, 
    const Date &dateOfBirth, const Data &dateOfHire) 
    : firstName(first), 
    lastName(last), 
    birthDate(dateOfBirth), 
    hireDate(dateOfHire) { }; 

書中說的成員的初始值如birthDate(dateOfBirth)調用Date類的拷貝構造。我很困惑爲什麼複製構造函數?我認爲「通過引用傳遞」的要點是爲了避免對象複製?

如果我做的:

Date birth(7,24, 1959); 
Date hire(2,12, 1988); 
Employer staff("bob", "blue", birth, hire); 

多少Date對象不繫統現在有2個或4? (在開始創建二,二是通過拷貝構造函數創建)

回答

13

這不是傳球模式,涉及到的副本。

這是invove副本成員的初始化(明顯的參數不住在類和類成員需要得到相同的值:複製)

讓我們來看看

Employee::Employee(const string &first, const string &last, 
    const Date &dateOfBirth, const Data &dateOfHire) 
    : firstName(first), 
    lastName(last), 
    birthDate(dateOfBirth), 
    hireDate(dateOfHire) { }; 

// 
int main() 
{ 
    const std::string fname = "test"; 
    Employee e(fname, /* ..... */); 
} 
  1. 我們調用Employee::Employee,由const&沒有複製)傳遞fname
  2. 構造函數初始化它是從第一個參數
  3. 此練習std::string(const std::string&),再由const&傳遞參數上(仍然沒有副本)的成員名字。
  4. std::string拷貝構造函數現在採取一切必要步驟,以複製的價值它的參數爲對象本身。 這是一份

這是有道理的,當你建立一個新的std::string(在這種情況下,員工的成員),它會導致...新std::string這一點。我認爲,以這種方式思考它使得它很容易掌握。

+0

因此,確有通過拷貝構造函數的行爲創造了2個新的Date對象,就像性病的新對象:被創建的字符串,我是否理解你正確?thx – Oliver 2012-02-08 21:15:26

+0

在這種情況下,對象實例顯示爲Employee類的成員,並且它們僅僅是_initialized_(通過它們的拷貝構造函數)就位。但從邏輯上說,是的,所有這些成員都被初始化爲它們各自初始化程序**和**的副本,它們剛剛開始生活,並作爲Employee對象的一部分進行分配。 **僱員有一個字符串,字符串,日期,日期**,可以這麼說 – sehe 2012-02-08 21:20:44

2

的點「按引用傳遞」是不是隻要員工的構造函數進行復制,但只有當你選擇初始化員工與傳遞的日期成員之一。

+0

簡潔措辭+1。 Nitpick:不涉及賦值,因爲成員從初始化程序列表中初始化_initialized_。 – sehe 2012-02-08 21:30:23

+1

C++,總是最好把你的腳放在你的嘴裏。 – Rhangaun 2012-02-08 22:04:23

+2

我不確定你的意思,但放心我說的很好:)我個人覺得(也是?)堅持正確的術語有時是無聊的,有時是_meh_,但它是建立更深的唯一方法理解(當你調用複製構造函數時,你還知道其他什麼東西?或者更確切地說是賦值運算符?這是相關的東西,如果你的類包含引用成員,那麼你可能會成爲一個顯示終止器。)無論如何,我會越來越偏離主題。乾杯 – sehe 2012-02-08 22:10:02

3

您的原始對象birth確實是通過引用Employee拷貝構造函數傳遞的,因此在該階段沒有拷貝。然而,Employee拷貝被constructred時,所述構件Employee::birthDate目的是通過使用其自身拷貝構造中,向其中外birth目的通過引用傳遞初始化,但當然是拷貝構造會使的副本birth對象,這成爲Employee::birthDate成員對象。

4

這兩條線將要調用日期的拷貝構造函數:

birthDate(dateOfBirth), 
hireDate(dateOfHire)