Подтвердить что ты не робот

Почему не называется конструктор копирования

Возможный дубликат:
Что такое оптимизация при копировании и возврате значений?

Мне трудно понять, почему в следующем фрагменте кода конструктор копирования не вызывается.

#include <iostream>

class Test
{
public:
  Test(int){std::cout << "Test()" << std::endl;}
  Test(const Test&){std::cout << "Test(const Test&)" << std::endl;}
};

int main()
{
  // Test test;
  Test test2(Test(3));

  return 0;
}

Может кто-нибудь объяснить, почему вызывается только конструктор и нет конструктора копирования?
Спасибо.

4b9b3361

Ответ 1

Это называется copy elision.
Компиляторам разрешено выполнять эту оптимизацию. Хотя он не гарантируется стандартом, любой коммерческий компилятор будет выполнять эту оптимизацию всякий раз, когда это возможно.


Стандартная ссылка:

С++ 03 12.8.15:

[...] Это разрешение операций копирования разрешено в следующих обстоятельства (которые могут быть объединены для устранения нескольких копий):

[...]

  • когда объект временного класса, который имеет не были связаны с ссылкой (12.2) будет скопирован в объект класса с тот же самый cv-неквалифицированный тип, копия операция может быть опущена построение временного объекта прямо в цель пропущенная копия

Вы можете использовать некоторые параметры компилятора, чтобы отключить эту оптимизацию, например, в случае gcc, на странице :

-fno-elide-constructor

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

Однако использование этого кода делает ваш код не переносимым для разных компиляторов.

Ответ 2

Это из-за оптимизации, выполняемой вашим компилятором. Компиляторам разрешено выполнять такие оптимизации, хотя это не требование, поэтому не гарантировано.

Обратите внимание на важный момент, что, хотя конструктор-копия не вызывается в конце концов, он доступен с семантической. То есть, если вы создадите конструктор-копию private, ваш код будет не компилироваться!! Это связано с тем, что семантическая проверка выполняется намного до фазы оптимизации, означает, что компилятор сначала проверяет, доступен ли конструктор копирования или нет; , если он доступен, тогда приходит только фаза оптимизации, в которой завершается копирование.

Ответ 3

Как уже упоминалось, это связано с оптимизацией вашего компилятора.

Я не проверял его, но вы могли бы скомпилировать свой код с оптимизацией и снова без него и посмотреть код ассемблера. Затем вы также должны определенно увидеть некоторые отличия.