Search code examples
c++operator-overloadingcopy-constructordefault-constructorfriend-function

How the invoking of parameterized constructor is executed?


There is this piece of code which have friend function and operator overloading , i'm getting an output that is making partially sense to be , so here is the code , the thing i'm not getting is that how the constructor having float type parameter is being called when the calls made in the are with object parameters.

class a
{
    public:
        a():n(3),d(2)
        {
            cout<<endl<<"default constructor called";
        }
        a(float f):n(f),d(1)
        {
            cout<<endl<<"type casting constructor called";
        }
        a(const a &f)
        {
            cout<<endl<<"copy constructor called";
        }
        friend a operator+( a x, a y);
};
a operator+(a x, a y)
{
    return x;
}

and there goes the main part

int main()
{
    a f1;

    float f=1.5;

    f1+f;

}

the problem exactly is how the parameterised constructor or the type casting contructor is getting invoked?

Output:
default constructor called


type casting constructor called
copy constructor called
copy constructor called

...

Solution

  • If I've got this right, you're wondering why the a(float f) constructor gets called when you add a float to an existing instance of a.

    So, this is caused by implicit construction, and it's happening because of a few things:

    1. You have a constructor which takes a float as a parameter.
    2. You have an operator+ overload which takes two instances of a.

    So when you perform your addition, the right-hand side variable is a float. Since you can instantiate a with a float, the constructor gets called to create an instance of a to add it to your left-hand side instance. You then get two copies, because the operator+ function takes two instances of a by copy.

    A step-by-step breakdown would be this:

    • a f1; // Outputs "default constructor called"
    • f1 + f; // "f" is a float, so we can construct an instance of "a".
    • f1 + a(f); // Outputs "type casting constructor called"
    • operator+(a x, a y); // Takes two copies, so outputs "copy constructor called" twice

    Since I explained what's going on, I figure I should also explain how to avoid it.

    If, for whatever reason, you don't want the implicit construction to take place, you can do one of two things:

    • Prefix the constructor that takes a float parameter with the explicit keyword, which means that constructor will never be called as part of an implicit conversion or copy-initialization. It will also no longer allow you to pass any parameters that could be converted into a float to it implicitly.
    • Declare and define another operator+ function that takes a float as its right-hand side parameter. Something like friend a operator+(a x, float y). This operator will be called instead of the current one, since it doesn't require a conversion to work.