Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the copy CTOR required even if never called?

consider the following:

class X {
public:
    X(int i) { cout << "X(int i)" << endl; }
    X(const X& x) { cout << "X(const X& x)" << endl; }
};

void main() {
    X x1(1);
    X x2 = X(1);
    X x3 = (X)1;
}

running this code produces this output:

X(int i)
X(int i)
X(int i)

I thought that all of the above three statements are equivalent as the copy CTOR is never called. However, changing X's copy CTOR to be private:

class X {
public:
    X(int i) { cout << "X(int i)" << endl; }
private:
    X(const X& x) { cout << "X(const X& x)" << endl; }
};

Will fail to compile (In visual studio 2010) with this error:

cannot access private member declared in class 'X'

So it seems the copy CTOR is involved somehow though I don't quite understand how.

Thanks

like image 495
dankilman Avatar asked Jun 10 '11 16:06

dankilman


People also ask

When a copy constructor is not called?

The reason the copy constructor is not called is because the copy constructor itself is a function with one parameter. You didn't call such function,so it didn't execute.

Do I need a copy constructor?

A user-defined copy constructor is generally needed when an object owns pointers or non-shareable references, such as to a file, in which case a destructor and an assignment operator should also be written (see Rule of three).

What is a copy constructor and when is it used?

The copy constructor is a constructor which creates an object by initializing it with an object of the same class, which has been created previously. The copy constructor is used to − Initialize one object from another of the same type. Copy an object to pass it as an argument to a function.

In what way a copy constructor is automatically invoked?

The copy constructor is invoked when the new object is initialized with the existing object. The object is passed as an argument to the function. It returns the object.


1 Answers

X x1(1);
X x2 = X(1);
X x3 = (X)1;

The reason is that all of these are not exactly equivalent.

First one is direct-initialization, while the second and third is copy-initialization. For copy-initialization, copy-constructor must be public, or else compiler will give error.

Now the question is, if 2nd and 3rd requires the copy-ctor to be public,then why the following output:

X(int i)
X(int i)
X(int i)

This surely says that copy-ctor is never called which is true. Compiler just elided the call to copy-ctor. According to §8.5/14, in such cases, the compiler is permitted to eliminate the need to call copy-constructor. That is why you don't see copy-ctor being called.

A little inside : in the 2nd and 3rd case, first a temporary is created by calling X(int i), then this temporary was supposed to be passed to the copy-ctor to copy-initialize the object being declared. But the compiler optimizes away this step, eliding the call to copy-ctor.

like image 130
Nawaz Avatar answered Sep 19 '22 01:09

Nawaz