2

I have a class.

class Books
{
private:
    int m_books;
public:
    Books(int books=0)
    {
        m_books = books;
    }

    Books(const Books &source)  //Here is what I don't understand.
    {
        m_books = source.m_books;
    }
};

I can't understand why it has to be Books(const Books &source), and not Books(const Books source).

Cœur
  • 37,241
  • 25
  • 195
  • 267
Some Stranger
  • 73
  • 1
  • 4

7 Answers7

9

When you have

Books(const Books &source)

the source is passed by reference. When you have

Books(const Books source)

it would have been passed by value. But to pass by value you are the copy constructor. So to avoid an infinite recursion, the copy constructor must accept a reference.

AProgrammer
  • 51,233
  • 8
  • 91
  • 143
8
Books(const Books &source)

means that a reference is passed, instead of the actual variable (as in pass-by-value, as in the case of primitives such as int or char).

In this case, since you are building a copy constructor, you don't want to make modification to the object whose reference is passed in, so the argument signature is prefixed with const (this guarantees that the argument being passed in is immutable)

(Note, mostly importantly: pass-by-value here would introduce infinite recursion - see @AProgrammer's answer) Aside from that, it also would be unnecessarily expensive to pass in source by value (meaning: make a copy of the entire source when the copy constructor is called), we just use a reference instead.


Additional reading you might be interested in: C++ Pass by Reference vs. Value

Community
  • 1
  • 1
sampson-chen
  • 45,805
  • 12
  • 84
  • 81
  • @sampson-chen, yes I posted my comment and then noticed that you updated. I removed it now. Regarding "unnecessarily expensive" - it sort of pointless to mention in the context of copy constructor, because it's simply impossible to do. –  Dec 07 '12 at 17:36
3

What you're looking at is called the copy constructor. The reason why you should pass an object by a reference is because if you pass it by a value then a copy of the object has to be constructed, so it would have to call the copy constructor again. And again. And again ...

prazuber
  • 1,352
  • 10
  • 26
1

So book is passed by reference instead of copied by value.

djechlin
  • 59,258
  • 35
  • 162
  • 290
1

Using a reference means that there's no copy involved. If you had:

Books(const Books source)

Then the argument the caller passes would have to be copied to source. If you use a reference instead, no copy is made. This provides better performance. With small amounts of data it doesn't matter much, because it's a simple class with no large amount of data. But with more complex classes, copying can be expensive. Using references avoids that problem.

However, in the case of copy constructors, avoiding a copy is vital. Not for performance reasons, but by the fact that copying involves a copy constructor. When the copy constructor gets called, another copy would have to be made if a reference was not used. That means another call to a copy constructor. There, yet another copy would have to be made. Yet another call to a copy constructor.

As you can imagine, this would result in an infinite amount of copy constructor calls. By using a reference this situation is avoided.

Nikos C.
  • 50,738
  • 9
  • 71
  • 96
0

Read about copy constructors: http://www.cplusplus.com/articles/y8hv0pDG/

Florin Petriuc
  • 1,146
  • 9
  • 16
0

It is passing in a reference to the Books source object. That it all.

I hope this helps.

MoonKnight
  • 23,214
  • 40
  • 145
  • 277