Почему не называется конструктор копирования
Возможный дубликат:
Что такое оптимизация при копировании и возврате значений?
Мне трудно понять, почему в следующем фрагменте кода конструктор копирования не вызывается.
#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;
}
Может кто-нибудь объяснить, почему вызывается только конструктор и нет конструктора копирования?
Спасибо.
Ответы
Ответ 1
Это называется copy elision.
Компиляторам разрешено выполнять эту оптимизацию. Хотя он не гарантируется стандартом, любой коммерческий компилятор будет выполнять эту оптимизацию всякий раз, когда это возможно.
Стандартная ссылка:
С++ 03 12.8.15:
[...] Это разрешение операций копирования разрешено в следующих обстоятельства (которые могут быть объединены для устранения нескольких копий):
[...]
- когда объект временного класса, который имеет не были связаны с ссылкой (12.2) будет скопирован в объект класса с тот же самый cv-неквалифицированный тип, копия операция может быть опущена построение временного объекта прямо в цель пропущенная копия
Вы можете использовать некоторые параметры компилятора, чтобы отключить эту оптимизацию, например, в случае gcc, на странице :
-fno-elide-constructor
Стандарт С++ позволяет реализации опускать создание временного объекта, который используется только для инициализации другого объекта того же типа. Указание этого параметра отключает эту оптимизацию и заставляет g++ вызывать конструктор копирования во всех случаях.
Однако использование этого кода делает ваш код не переносимым для разных компиляторов.
Ответ 2
Это из-за оптимизации, выполняемой вашим компилятором. Компиляторам разрешено выполнять такие оптимизации, хотя это не требование, поэтому не гарантировано.
Обратите внимание на важный момент, что, хотя конструктор-копия не вызывается в конце концов, он доступен с семантической. То есть, если вы создадите конструктор-копию private
, ваш код будет не компилироваться!! Это связано с тем, что семантическая проверка выполняется намного до фазы оптимизации, означает, что компилятор сначала проверяет, доступен ли конструктор копирования или нет; , если он доступен, тогда приходит только фаза оптимизации, в которой завершается копирование.
Ответ 3
Как уже упоминалось, это связано с оптимизацией вашего компилятора.
Я не проверял его, но вы могли бы скомпилировать свой код с оптимизацией и снова без него и посмотреть код ассемблера. Затем вы также должны определенно увидеть некоторые отличия.