поведение конструктора и конструктора копирования в С++

У меня есть следующий код:

#include <iostream>
using namespace std;

class X
{
public:
    int g;
    X() { cout << "constr" << endl; }
    X(const X& ref1) { cout << "copy constr" << endl; }
};

X f()
{
    X ee;
    ee.g = 1;
    return ee;
}

int main()
{
    X ff = f();
    return 0;
}

Запустив код, я вижу, что конструктор вызывался только один раз, а конструктор копирования никогда не вызывался. Разве вы не ожидаете, что здесь вызовет два конструктора и один конструктор копирования? Спасибо!


person hovnatan    schedule 08.03.2014    source источник


Ответы (2)


Это особый случай копирования, называемого оптимизация возвращаемого значения (ссылка объясняет именно ваш случай).

person bobah    schedule 08.03.2014

Copy Elision — это оптимизация, реализованная многими компиляторами для предотвращения лишних ненужных копий. Делает возможным возврат по значению или передачу по значению на практике.

Взгляните на пример в следующем ответе: https://stackoverflow.com/a/12953129/1938163

struct C {
  C() {}
  C(const C&) { std::cout << "A copy was made.\n"; }
};

C f() {
  return C();
}

int main() {
  std::cout << "Hello World!\n";
  C obj = f();
}

(http://en.wikipedia.org/wiki/Return_value_optimization#Summary)

Возможно, невероятно поверить в первый раз, в зависимости от компилятора и настроек, все следующие результаты верны:

Hello World! 
A copy was made. 
A copy was made. 

Hello World! 
A copy was made.

Hello World!

В вашем случае это специальная оптимизация удаления копии, называемая RVO — оптимизация возвращаемого значения, где объект возвращаемое значением из метода, его копия опущена.

person Marco A.    schedule 08.03.2014
comment
при вырезании/вставке из Википедии вы обычно прямо указываете это - person bobah; 08.03.2014
comment
Я разместил ссылку полностью, но я упомяну об этом, если хотите. - person Marco A.; 08.03.2014