Search code examples
c++copy-constructorimplicit-conversionassignment-operator

Constructor behavior in case of default, parameterized, copy ctor and assignment operator


I was going through Thinking in C++ and have some confusion regarding the behaviors of constructors in C++. Here is my sample code:

#include<iostream>
using namespace std;

class base
{
    public:
           int a;

/*Ctor 1*/           base()  { cout<<"  default"<<endl; }

/*Ctor 2*/           base(int a){ cout<<"  base::int "<<endl; }

/*Ctor 3*/           base(const base& b) { cout<<"  base::cc "<<endl; }

/*Asgn 1*/           base operator=(base b){ 
                     cout<<"  base::assignment - base"<<endl;
                     return b;
                 }

/*Asgn 2*/     /*      base operator=(int b){
                     cout<<"  base::assignment - int"<<endl;
                     return (base)b;
                 } */
};
int main()
{
    base b;
    int a = 10;
    b = a;
    system("PAUSE");
    return 0;
}

Output :

program output

Could anyone please explain me the output ? I expected just a call to

  1. Default constructor.
  2. Parameterized constructor.

I am unable to understand why I get a call to assignment operator and copy constructor other object being "int" type. If I uncomment "Asgn 2' I get a call to it rather that Asgn 1 which is understandable.

If I am getting a call to copy constructor (which always take object reference as its parameter), is it because compiler casts int to base type?


Solution

  • The output

    default
    base::int 
    base::assignment - base
    base::cc 
    

    Comes about as follows:

    base b;
    

    Here create a b - This will use the default constructor

    int a = 10;
    b = a;
    

    We have an assignment - the only one available takes a value of type base - so the compiler scratches its head and say "ah-ha" got a version of a constructor that can create an object of type base from an int. We can use that.

    So you get the output

    cout<<"  base::int "<<endl;
    

    Now the compiler can use the assignment operator. The parameter is an object of type base but as it is temporary this does not need to be called (see http://en.cppreference.com/w/cpp/language/copy_elision), The assignment operator then outputs

    cout<<"  base::assignment - base"<<endl;
    

    But the assignment returns the value not as a reference - so it need to copy this return value into b - thus calling the copy constructor. Hence

    cout<<"  base::cc "<<endl;