Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does passing by reference involve a copy constructor?

Tags:

c++

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)

like image 503
Oliver Avatar asked Feb 08 '12 20:02

Oliver


People also ask

Does passing by reference call copy constructor?

When an object (or built-in type) is passed by reference to a function, the underlying object is not copied. The function is given the memory address of the object itself. This saves both memory and CPU cycles as no new memory is allocated and no (expensive) copy constructors are being called.

Why reference is used in copy constructor and not pointer?

Passing by references ensures an actual object is passed to the copy constructor, whilst a pointer can have NULL value, and make the constructor fail.

Why we Cannot pass object by value to a copy constructor?

Passing by value (rather than by reference) means a copy needs to be made. So passing by value into your copy constructor means you need to make a copy before the copy constructor is invoked, but to make a copy you first need to call the copy constructor.

Does reference create copy?

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.


2 Answers

It is not the passing-mode that involves a copy.

It is the initialization of the members that invove 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.

like image 52
sehe Avatar answered Sep 26 '22 16:09

sehe


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.

like image 34
Kerrek SB Avatar answered Sep 23 '22 16:09

Kerrek SB