Search code examples
c++c++11constructorcopy-constructorcopy-assignment

C++: What is the output, if no optimizations are applied to these different ways to create/initialize, copy, assign?


I found a bit of confusion in the ways a variable is constructed, copied, assigned because in the compilers I tried they usually apply some kind of optimization (remove temporary etc.).

I'm listing the different ways I tried and the output of my program in comments below. May be some of them included temporary object creation but are optimized away by the compiler? Please mention if the output is correct as per the standard and what is the output if no optimizations are applied.

#include <iostream>
using namespace std;

class type {
    public:
    type(int z){cout << "ctor"<<endl;};
    type(const type&){cout<<"copy"<<endl;}
    void operator=(const type& ){cout <<"assign"<<endl;}
};
int main()
{
//constructor
type c(8);         //ctor 
type c2{8};        //ctor 
type c3 = 8;       //ctor  
type c4 = {8};     //ctor
type c5 = type(8); //ctor
type c6 = type{8}; //ctor
cout <<endl; 

//copy 
type ci0(c);        //copy
type ci1{c};        //copy
type ci2 = c;       //copy
type ci3 = {c};     //copy
type ci4 = type(c); //copy
type ci5 = type{c}; //copy
cout <<endl;

//assign
c2 = c;        //assign
c2 = {c};      //assign
c2 = type{c};  //copy and then assign
c2 = type(c);  //copy and then assign
c2 = 8;        //ctor and then assign
c2 = {8};      //ctor and then assign
c2 = type(8);  //ctor and then assign
c2 = type{8};  //ctor and then assign
}

Solution

  • Using explicit to ctor and copy ctor and deleting each of the functions, I was able to get below results.

    //constructor
    type c(8);         //explicit ctor 
    type c2{8};        //explicit ctor 
    type c3 = 8;       //implicit ctor, explicit copy  
    type c4 = {8};     //implicit ctor
    type c5 = type(8); //explicit ctor, implicit copy
    type c6 = type{8}; //explicit ctor, implicit copy
    cout <<endl; 
    
    //copy 
    type ci0(c);        //explicit copy
    type ci1{c};        //explicit copy
    type ci2 = c;       //implicit copy
    type ci3 = {c};     //implicit copy
    type ci4 = type(c); //implicit copy
    type ci5 = type{c}; //implicit copy
    cout <<endl;
    
    //assign
    c2 = c;        //assign
    c2 = {c};      //assign
    c2 = type{c};  //implicit copy and then assign
    c2 = type(c);  //implicit copy and then assign
    c2 = 8;        //implicit ctor and then assign
    c2 = {8};      //implicit ctor and then assign
    c2 = type(8);  //explicit ctor and then assign
    c2 = type{8};  //explicit ctor and then assign