5

Why we have to use a reference in argument of copy constructor instead of a pointer? This questions was asked in an interview. I replied the following points:

  1. References can not be NULL.
  2. If we use pointer, then it would not be a copy constructor.
  3. The standard specifies so (section 12.8.2).

But the interviewer was not satisfied. He said it was 'related to inheritance and virtual functions'. I need help or some relevant points with which I can be able to think of an answer in that direction.

user207421
  • 305,947
  • 44
  • 307
  • 483
karan
  • 79
  • 1
  • 7
  • 6
    I think your interviewer is suffering from the Dunning-Kruger effect. – Brian Bi Aug 30 '16 at 03:44
  • Related: [Why should the copy constructor accept its parameter by reference in C++?](http://stackoverflow.com/questions/2685854/why-should-the-copy-constructor-accept-its-parameter-by-reference-in-c). BTW your reasons are correct. I am not aware of any other caveats especially for inheritance or polymorphism. In fact pointers cannot reflect object as they are mere addresses. No comparison between reference & pointer in this regard. – iammilind Aug 30 '16 at 03:48
  • If we used a pointer than the parameter would be a copy of the pointer, not the object. A copy constructor needs to copy the object. – Galik Aug 30 '16 at 03:48
  • Apart from inability to pass `NULL`s legally, there is nothing that would make a pointer preferable to a reference. You are right and your interviewer is wrong. – Sergey Kalinichenko Aug 30 '16 at 03:53
  • 3
    Was he perhaps asking why the standard defines it that way? – Benjamin Lindley Aug 30 '16 at 03:55
  • 1
    Most important driving factor for having references is `creating an object from temporaries or passing temporaries to a function by value` like `f(a+b)` -- where a & b are object of class `A` and `f` is as `A::f(A obj)` – g-217 Aug 30 '16 at 04:10
  • Your points are all correct, although (2) and (3) are really the same. The interviewer is mistaken to look for any further explanation, and the reasons he advanced are certainly spurious. In the ARM, Stroustrup defines it as follows: 'a copy constructor for class `X` is a constructor that can be called with a single argument of type `X`', excluding the pass-by-value case; and he doesn't say anything about it at all in *The Design and Evoution of C++* that I can find quickly. – user207421 Aug 30 '16 at 04:13
  • The interviewer's response implies that he thinks there is a relevant semantic difference between pass-by-reference and pass-by-pointer. Which there isn't. The only sense I can make of it is that he is thinking of object-slicing, which only happens in pass-by-*value*, which is specifically excluded. – user207421 Aug 30 '16 at 05:16

2 Answers2

2

Your interviewer was wrong, and you are correct.

The most important aspect of your answer is 2. and 3 (which are essentially the same points, but worded differently): because the standard says so (see 12.8.2):

A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments (...).

We use references instead of pointers because the standard says so. It's not a copy constructor otherwise.

When it comes to inheritance and virtual functions, references can do everything that a pointer can.

The only other reason you could've provided, as Gautam Jha points out in the comments, is that a reference allows you to make a copy from temporaries.

Community
  • 1
  • 1
Tas
  • 7,023
  • 3
  • 36
  • 51
2

You points look sensible, and I cannot figure out what your interviewer wanted to hear from you.

But, as far as I know, enabling a uniform syntax for copy constructors and assignment operators was a significant reason why Stroustrup introduced references. For example, let's assume we have no references in C++ and we want to do some copy-construction, passing an argument by pointer:

class MyClass {
    // Copy ctor and assignment operator are declared
    // like this in our referenceless "C with classes" language:
    MyClass(const MyClass* const);
    MyClass* operator=(const MyClass* const);
};

MyClass a, b, c;

//Let's copy-construct:
MyClass d = &a; // Dereferencing looks ugly.

//Let's assign:
a = &b; // Dereferencing again.

// Even worse example:
a = b = c = &d; // Only the last variable should be dereferenced.
a = b = &c; // Awfully inhomogeneous code.
/*
The above line is equivalent to a = (b = &c),
where (b = &c) returns a pointer, so we don't need to
dereference the value passed to assignment operator of a.
*/

And this is obviously not how built-in types work:

int a, b, c;
int d = a;
a = b = c = d;

So references were introduced to resolve these inhomogeneities.

UPD

For an authoritative proof of this point, please refer to the § 3.7 of Stroustrup's The Design and Evolution of C++. Unfortunately, I have no English text of the book, but the first sentence in the chapter is (back-translated into English):

References were introduced basically for operator overloading support.

And in the next few pages Stroustrup covers the topic in-depth.

Sergey
  • 7,985
  • 4
  • 48
  • 80