Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explicit copy constructor behavior and practical uses

Tags:

c++

A recent question got me wondering about explicit copy constructors. Here is a sample code that I tried compiling under Visual Studio 2005 :

struct A {     A() {}     explicit A(const A &) {} };  // #1 > Compilation error (expected behavior) A retByValue() {     return A(); }  // #2 > Compiles just fine, but why ? void passByValue(A a) { }  int main() {     A a;     A b(a); // #3 > explicit copy construction : OK (expected behavior)     A c = a; // #4 > implicit copy construction : KO (expected behavior)      // Added after multiple comments : not an error according to VS 2005.     passByValue(a);     return 0; } 

Now for the questions :

  • Is #2 allowed by the standard ? If it is, what is the relevant section describing this situation ?
  • Do you known of any practical use for an explicit copy constructor ?

[EDIT] I just found a funny link on MSDN with the exact same situation, and a mysterious comment from the main function : "c is copied" (as if it was obvious). As pointed by Oli Charlesworth : gcc does not compile this code and I believe he's right not to.

like image 539
icecrime Avatar asked Nov 11 '10 10:11

icecrime


People also ask

What are copy constructors used for?

A copy constructor is a member function of a class that initializes an object with an existing object of the same class. In other words, it creates an exact copy of an already existing object and stores it into a new object.

What is the advantage of copy constructor?

Advantages of Copy ConstructorIf a field declared as final, the copy constructor can change it. There is no need for typecasting. Its use is easier if an object has several fields. Addition of field to the class is easy because of it.


1 Answers

I believe the relevant sections of C++03 are §12.3.1 2:

An explicit constructor constructs objects just like non-explicit constructors, but does so only where the direct-initialization syntax (8.5) or where casts (5.2.9, 5.4) are explicitly used. A default constructor may be an explicit constructor; such a constructor will be used to perform default-initialization or value-initialization (8.5).

and § 8.5 12:

The initialization that occurs in argument passing, function return, throwing an exception (15.1), handling an exception (15.3), and brace-enclosed initializer lists (8.5.1) is called copy-initialization and is equivalent to the form

    T x = a; 

The initialization that occurs in new expressions (5.3.4), static_cast expressions (5.2.9), functional notation type conversions (5.2.3), and base and member initializers (12.6.2) is called direct-initialization and is equivalent to the form

    T x(a); 

Calling passByValue(a) involves copy-initialization, not direct-initialization, and thus should be an error, according to C++03 § 12.3.1 2.

like image 134
outis Avatar answered Sep 28 '22 06:09

outis