2012-08-13 3 views
2

Когда вызывается [abc e = a + b], конструктор копирования не вызывается.Почему конструктор копирования не вызывается, если перегруженные операторы + и = возвращаются по значению в следующем случае?

class abc{ 
     int i; 
     public: 
     abc() 
      { 
      i = 10; 
      cout<<"constructor"<<endl; 
     } 
     abc(const abc &a) 
     { 
      cout<<"copy constructor"<<endl; 
      i = a.i; 
     } 
     abc operator=(const abc &a) 
     { 
      cout<<"operator="<<endl; 
      abc temp; 
      temp.i = a.i; 
      return temp; 
     } 
     abc operator+(abc& a) 
     { 
      cout <<"Operator+ called"<<endl; 
      abc temp; 
      temp.i = i+a.i; 
      return temp ; 
     } 
    }; 

    int main() 
    { 
     abc a,b; 
     cout <<"----------------------------------------------"<<endl; 
     a = b; 
     cout <<"----------------------------------------------"<<endl; 
     abc c = a; 
     cout <<"-----------------------------------------------"<<endl; 
     abc d(a); 
     cout <<"-------------------------------------------"<<endl; 
     **abc e = a+b;** 
    } 

Однако, если операторы перегрузки методы заменяются следующими методами, которые возвращают ссылки на объект класса аЬс, конструктор копирования вызывается.

abc& operator=(const abc &a) 
    { 
     cout<<"operator="<<endl; 
     i = a.i; 
     return *this; 
    } 
    abc& operator+(const abc& a) 
    { 
     cout <<"Operator+ called"<<endl; 
     i = i+a.i; 
     return *this ; 
    } 

Может кто-нибудь объяснить, почему это происходит?

+2

Возможный дубликат [Не является оптимизацией возвращаемого значения (RVO) ошибка?] (Http://stackoverflow.com/questions/3905869/isnt-return-value-optimization-rvo-a-bug) – iammilind

+0

плохой класс имя. вы можете назвать это 'MyClass',' TestClass' или некоторые другие имена, но не 'abc', особенно когда ваше имя переменной' a' 'b' и' c'. – abcdabcd987

ответ

1

Это происходит из-за return value optimization.

Поскольку никаких дорогостоящих операций копирования памяти не производится, если ваш конструктор возвращает ссылку, он работает так, как вы ожидали бы, потому что в этом случае оптимизация не выполняется. Если он возвращает значение, оптимизация срабатывает и работает несколько неожиданно (для вас), но это разрешено стандартом.

+0

Предполагаю, что вы говорите об «разрешении операции копирования». Я был удивлен, потому что он использовался в случае возврата по значению, но не в обратном случае. Спасибо, что разъяснил то же самое. – Abhijeet

0

Его оптимизация явно разрешена стандартом.

В пункте n3376
12.8 31:

При соблюдении определенных критериев, реализация может пропустить копирование/перемещение строительство объекта класса, даже если конструктор выбран для копирования/перемещения операция и/или деструктор объекта имеют побочные эффекты.

Эта оптимизация может быть достигнута с помощью RVO (этот случай) и при определенных условиях NRVO.

0

Вы можете отключить параметры оптимизации на своем компиляторе. Проверьте флаг оптимизации, используемый при компиляции кода.

Смежные вопросы