Search code examples
c++copy-constructorassignment-operator

Why Paramaterized constructor called when assignment is happening?


My question is for the last statement i.e. before return 0;

Why the parametrize constructor is being called when we are trying to assign an int value to an object.

My piece of code:

#include<iostream>
using namespace std;
class Test {
private:
    int i;
    public:
    Test(int s=0):i(s) {
            cout<<"param ctor: "<<i<<endl;
    }
};

int main()
{
    Test a;         //param ctor called
    Test b(5);      //param ctor called
    //b(a);         //error as we have not implemented copy ctor
    b=a;            //compiler provided assignment opr. called
    b=100;          //why param ctor called for this.??
    return 0;
}

OUTPUT:

  param ctor: 0
  param ctor: 5
  param ctor: 100

Solution

  • The reason is simple: every class X has a copy constructor (a consturctor taking X) and a copy assignment operator (an assignment operator taking X). If you don't declare these yourself, the compiler declares them for you implicitly. In some cases, they are defined as deleted (which means it is an error to use them), but they're always there.

    So when you do this:

    b = 100;
    

    it's effectively translated to this:

    b.operator=(100)
    

    and the best matching overload of operator= is searched for. There's only one overload, actually: the implicitly declared copy-assignment operator Test& Test::operator=(const Test &), so the compiler checks if it could convert the argument 100 to the assignment operator's parameter type const Test &. And it turns out that it can, thanks to the converting constructor Test::Test(int), so that is what ends up called.

    If you want to disable such behaviour, you can mark the constructor as explicit. This will prevent it from being used for implicit conversions, such as the one converting 100 to the type of the assignment operator's parameter.