2015-07-15 4 views
1

Я написал:Понимание копирование объектов

#include <iostream> 

struct A 
{ 
    int a; 
    int b; 
    A() : a(10) { std::cout << "default ctor" << std::endl;} 
    ~A(){ } 
    A(const A&){ std::cout << "copy ctor" << std::endl; } 
    A(const A&&){ std::cout << "move ctor" << std::endl; } 
}; 

A init() 
{ 
    A a; 
    a.b = 20; 
    return a; 
} 

int main() 
{ 
    A a = init(); 
    std::cout << a.b << std::endl; 
} 

Я ожидал, что A a = init() навязывает вызов шаг-застройщик, но outpur является:

default ctor 

20 

DEMO

+0

«RVO» зависит от компилятора - VS2012 работает в отладочной работе, как и следовало ожидать, но в выпуске он ведет себя так же, как и ваша демонстрация, поэтому компилятор лучше решает встраивание. –

ответ

1

Линия

A a = init(); 

Введено в действие NRVO. Он создает объект, используя его конструктор по умолчанию в своем сегменте кода:

A a; 

Ваш ход конструктор не будет использоваться здесь.

Конструктор перемещения здесь может использоваться с флагом компилятора -fno-elide-constructors. У меня есть modified your example, чтобы скомпилировать его с этим флагом. Но учтите, что конструктор по умолчанию всегда будет вызван, потому что NRVO не влияет на это в вашем коде. NRVO означает, что объект будет построен в том хранилище, которое необходимо (не в стеке вашего метода init), поэтому он не будет перемещен или скопирован. С флагом no-elide он не может быть создан там, поэтому он будет скопирован/перемещен.

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