为什么通过引用传递涉及复制构造函数

Why does passing by reference involve a copy constructor?

本文关键字:复制 构造函数 引用 为什么      更新时间:2023-10-16

在Deitel C++书("程序员的C++11",第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个?(两个在开始时创建,两个由复制构造函数创建)

它不是涉及副本的传递模式。

它是涉及副本的成员的初始化(显然?参数不存在于类中,类成员需要获得相同的值:副本)

让我们检查

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(在本例中是Employee的成员)时,它会导致。。。新的CCD_ 10。我认为,这样想会让它很容易掌握。

您的原始对象birth确实是通过引用传递给Employee复制构造函数的,因此在该阶段不会进行复制。然而,当构造Employee副本时,成员Employee::birthDate对象是通过使用其自己的副本构造函数初始化的,外部birth对象通过引用传递到该副本构造函数,但该副本构造函数当然会复制birth对象,该对象将成为Employee::birthDate成员对象。

"pass-by-reference"的要点是,在调用Employee构造函数时不要立即进行复制,而只能在您选择用传递的日期初始化Employees的一个成员时进行复制。

这两行将调用Date的复制构造函数:

 birthDate(dateOfBirth),
 hireDate(dateOfHire)