2013-09-26 9 views
1

Для следующего кода:Почему здесь не вызывается конструктор копирования?

#include<iostream> 
    using namespace std; 

    class Test 
    { 
    public: 
     Test(const Test &t) { cout<<"Copy constructor called"<<endl;} 
     Test()  { cout<<"Constructor called"<<endl;} 
    }; 

    Test fun() 
    { 
     cout << "fun() Called\n"; 
     Test t; 
     return t; 
    } 

    int main() 
    { 
     Test t1; 
     Test t2 = fun(); 
     return 0; 
    } 

Я очень смущен относительно того, когда вызывается конструктор копирования? Например, если я запускаю указанную выше программу, то конструктор копирования не вызывается. Это означает, что если я запутался с параметрами, переданными конструктору копирования (исключая ключевое слово const), он не должен показывать какую-либо ошибку компилятора. Но его не показывая

"нет подходящей функции для вызова 'Test :: Test (тест)"

Кроме того, удовольствие() возвращает объект испытания типа, который создается во время fun(). Почему конструктор копирования здесь не называется?

int main() 
    { 
     fun(); 
     return 0; 
    } 

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

int main() 
    { 
     Test t2 = fun(); 
     Test t3 = t2; 
     return 0; 
    } 
+3

возможно дубликат [Почему конструктор копирования не вызывается в этом коде] (HTTP: // StackOverflow .com/questions/7779827/why-is-copy-constructor-not-being-called-in-this-code) –

+0

Конструктор копирования вызывается как ожидается на VC++ 2013 RC. – xmllmx

+2

@xmllmx: Даже в режиме выпуска? Потому что этого на самом деле не следует ожидать, если на современном компиляторе с оптимизацией. –

ответ

4

Это потому, что здесь используется копия инициализации, а не конструктор копирования, из-за включенного в ваш компилятор NRVO. Вы должны указать

-fno-elide-constructors

флага на НКЕ

Стандарта C++ позволяет реализации опускать создание временного , который используется только для инициализации другого объекта того же типа. Указание этого параметра отключает эту оптимизацию и заставляет G ++ вызвать конструктор копирования во всех случаях.

или скомпилировать его с cl /Od program.cpp на VS (/ O1 и O2/enables NRVO)

C++ : Avoiding copy with the “return” statement

1

Когда я запускаю свой код в VS2010, я получаю правильный результат:

1.

Constructor called 
fun() Called 
Constructor called 
Copy constructor called 

2.

fun() Called 
Constructor called 
Copy constructor called 

3.

fun() Called 
Constructor called 
Copy constructor called 
Copy constructor called 

Конструктор копирования был вызван правильно.

+0

Но на ideone и dev C++ его не показывали результаты, как ожидалось. Почему это так ? – SlashGeek

+0

Хотя было бы неправильно говорить, что это неправильные результаты, они не единственные правильные результаты. Однако они обычно не являются желаемыми результатами. И если это результаты с включенными оптимизациями (которые, как я подозреваю, это не так), то это недостаток в компиляторе VS2010, даже если результаты технически правильны. –

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