Перегрузка оператора C ++ и конструктор копирования - PullRequest
7 голосов
/ 31 января 2012

Мне трудно сосредоточиться на следующем (в частности, на сценарии b): (Предположим, что я определил оператор присваивания, оператор сложения и конструктор копирования только для вывода факта, что они вызываются)

сценарий 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

- Это все прекрасно, Денди

сценарий b (поведение, которое я не могу понять):

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

Вопрос, который у меня возникает, заключается в том, что в сценарии b конструктор копирования вызывается непосредственно перед оператором присваивания? Насколько я понимаю, конструктор копирования будет вызываться только для неинициализированного объекта. Однако в этом сценарии объект f был инициализирован в строке, предшествующей добавлению.

Объяснение будет с благодарностью.

Извиняюсь за то, что не опубликовал исходный код сразу (и из-за отсутствия отступов - у меня проблемы с копированием в текстовую область). Здесь все во всей своей простоте. Я использую Visual Studio 2005. К сожалению, я еще не очень знаком с его работой, поэтому не могу указать параметры оптимизации, которые передаются компилятору.

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;
}

Конечно, объяснение Немо - это то, что может понять мой начинающий ум C ++:)

После изменения уровня оптимизации на / O2, я вижу результат сценария b следующим образом (и то, что я ожидал)

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

Спасибо всем за ваши предложения.

1 Ответ

5 голосов
/ 31 января 2012

Ваш оператор + возвращает объект по значению, что может привести к вызову конструктора копирования, если компилятор не elide .

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

Код:

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

Вот пошаговый анализ:

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 `=`  
...