Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ operator overloading and the copy constructor

I'm having difficulty wrapping my mind around the following (specifically, scenario b): (Assume I have defined an assignment operator, addition operator, and copy constructor just to output the fact that they are being called)

scenario a:

Simple a;
Simple b;
Simple c = a + b;

    The output is as follows:
    Simple constructor called
    Simple constructor called
    Simple add operator call
    Simple constructor called
    copy constructor called

-- This is all fine and dandy

scenario b (the behavior that I cannot understand):

Simple d;
Simple e;
Simple f;
f = d + e;

    Simple constructor called
    Simple constructor called
    Simple constructor called
    Simple add operator called
    Simple constructor called
    copy constructor called
    assignment operator called

The question that I have is that in scenario b, why is the copy constructor called right before the assignment operator is? To my understanding, a copy constructor will only be called on an uninitialized object. However, in this scenario, the object f has been initialized in the line preceding the addition.

An explanation would be greatly appreciated.

Apologies for not posting the source code right away (and for the lack of indentation - I am having problems copying to the textarea). Here it is in all of it's simplicity. I am using Visual Studio 2005. Unfortunately, I am not that familiar with the workings of it yet, hence I cannot specify the optimization parameters that are being passed to the compiler.

class Simple
{
public:
    Simple(void);
Simple operator +(const Simple& z_Simple) const;
Simple& operator =(const Simple& z_Simple);
Simple(const Simple& z_Copy);
int m_Width;
int m_Height;
public:
~Simple(void);
};


#include "Simple.h"
#include <iostream>

using std::cout;
using std::endl;

Simple::Simple(void)
{
this->m_Height = 0;
this->m_Width = 0;
cout << "Simple constructor called" << endl;
}

Simple::Simple(const Simple& z_Copy)
{
cout << "copy constructor called" << endl;
this->m_Height = z_Copy.m_Height;
this->m_Width = z_Copy.m_Width;
}

Simple& Simple::operator =(const Simple &z_Simple)
{
cout << "assignment operator called" << endl;
this->m_Height = z_Simple.m_Height;
this->m_Width = z_Simple.m_Width;   
return *this;
}


Simple Simple::operator +(const Simple &z_Simple) const
{
cout << "Simple add operator called" << endl;
int y_Height = this->m_Height + z_Simple.m_Height;
int y_Width = this->m_Width + z_Simple.m_Width;
Simple y_Ret;
y_Ret.m_Height = y_Height;
y_Ret.m_Width = y_Width;
return y_Ret;
}

Simple::~Simple(void)
{
cout << "destructor called" << endl;
}

Certainly Nemo's explanation is the one that my novice C++ mind can grasp :)

After changing the optimization level to /O2, I can see the output of scenario b as follows (and what I would have expected)

    Simple constructor called
    Simple constructor called
    Simple constructor called
    Simple add operator called
    Simple constructor called
    assignment operator called

Thank you all for your suggestions.

like image 749
Michael Avatar asked Jan 31 '12 02:01

Michael


1 Answers

Your + operator returns a object by value, which might result in call to copy constructor if the compiler did not elide it.

Simple Simple::operator +(const Simple &z_Simple) const
{
    //......
    Simple y_Ret;
    //......
    return y_Ret;
}

Code:

Simple d;
Simple e;
Simple f;
f = d + e;

Here is a step by step analysis:

Simple constructor called     ---> creation of `d`
Simple constructor called     ---> creation of `e`
Simple constructor called     ---> creation of `f`
Simple add operator called    ---> Inside Addition operator
Simple constructor called     ---> creation of local `y_Ret`
copy constructor called       ---> `y_Ret` returned by value 
assignment operator called    ---> Result returned by `+` used for `=`  
like image 177
Alok Save Avatar answered Sep 30 '22 04:09

Alok Save