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.
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 `=`
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With