Oliver
Oliver

Reputation: 3682

Why does passing by reference involve a copy constructor?

In Deitel C++ book ("C++11 for Programmers", p.286) , there is an example of:

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) { };

The book says the member initializer such as birthDate(dateOfBirth) invoked Date class's copy constructor. I am confused as to why copy constructor? I thought the whole point of "pass by reference" is to avoid the object copy?

If I do:

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

How many Date objects does the system have now, 2 or 4? (Two created at the start, two are created by copy constructor)

Upvotes: 16

Views: 14254

Answers (4)

sehe
sehe

Reputation: 393064

It is not the passing mode that involves a copy.

It is the initialization of the members that involve a copy (obviously? the parameters don't live in the class, and the class members need to get the same value: copy)

Let's examine

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. We invoke Employee::Employee, passing fname by const& (no copy).
  2. The constructor initializes it's member firstname from the first parameter
  3. This exercises std::string(const std::string&), again passing the parameter on by const& (still no copy).
  4. The std::string copy constructor now takes all necessary steps to copy the the value of it's parameter into the object itself. This is the copy

It makes sense that when you construct a new std::string (in this case as a member of Employee), it results in a ... new std::string. Thinking of it this way makes it very easy to grasp, I think.

Upvotes: 25

Rhangaun
Rhangaun

Reputation: 1490

The point of "pass by reference" is to not make a copy as soon as Employee constructor is called, but only when you choose to initialize one of Employee's member with the Date passed.

Upvotes: 5

BЈовић
BЈовић

Reputation: 64223

These two lines are going to invoke the Date's copy constructor :

 birthDate(dateOfBirth),
 hireDate(dateOfHire)

Upvotes: 4

Kerrek SB
Kerrek SB

Reputation: 477040

Your original object birth is indeed passed by reference to the Employee copy constructor, so no copy is made at that stage. However, when the Employee copy is being constructred, the member Employee::birthDate object is initialized by using its own copy constructor, to which the outer birth object is passed by reference, but that copy constructor will of course make a copy of the birth object, which becomes the Employee::birthDate member object.

Upvotes: 5

Related Questions