конструктор и поведение на конструктор за копиране в c++

Имам следния код:

#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
когато изрязвате/поставяте от Wikipedia, вие обикновено споменавате това изрично - person bobah; 08.03.2014
comment
Публикувах линка изцяло, но ще го спомена, ако искате. - person Marco A.; 08.03.2014