C++ конструктор копирования, временные и семантика копирования
для этой программы
#include <iostream>
using std::cout;
struct C
{
C() { cout << "Default C called!n"; }
C(const C &rhs) { cout << "CC called!n"; }
};
const C f()
{
cout << "Entered f()!n";
return C();
}
int main()
{
C a = f();
C b = a;
return 0;
}
вывод, который я получаю:
Entered f()!
Default C called!
CC called!
С f()
возвращается по значению, он должен вернуть временное. As T a = x;
is T a(x);
, не вызовет ли он конструктор копирования для построения a
, С временной передачей в качестве аргумента?
3 ответов
С
f()
возвращается по значению, он должен вернуть временное. AsT a = x;
isT a(x);
, не вызовет ли он конструктор копирования для построенияa
, С временным переданным в качестве аргумента?
Поиск оптимизации возвращаемого значения. Это включено по умолчанию. Если вы находитесь в Windows, используя MSVC 2005+, вы можете использовать /Od
выключить это и получить желаемый результат (или -fno-elide-constructors
на GCC). Кроме того, для MSVC см. этой статья.
12.8 копирование объектов класса
15 при соблюдении определенных критериев, реализация позволяет опустить копировать построение объекта класса, даже если конструктор копирования и/или деструктор для объекта have side эффекты. В таких случаях реализация рассматривает источник и цель опущенной операции копирования как просто два разных способа ссылаясь на один и тот же объект, разрушение объекта происходит в позднее время, когда два объекты был уничтожен без оптимизация.115 этот Элизия копия операции разрешены в следующие обстоятельства (которые могут быть в сочетании устранить несколько копии):
- в инструкции return в a функция с типом возврата класса, когда выражение является именем энергонезависимой автоматический объект с же резюме-неквалифицированный тип, как этот тип возврата функции, копия операция может быть пропущена построение автоматического объекта непосредственно в возврат функции значение - в броске-выражение, когда операнд-это имя энергонезависимой автоматический объект, копия операции с операндом объект исключения (15.1) можно опустить путем построения автоматического объекта непосредственно в объект исключения
- когда временный объект класса, который имеет не был связан с ссылка (12.2) будет скопирован в объект class с тем же резюме-неквалифицированный тип, копия операция может быть пропущена строительство временного объекта прямо в цель опущена копия
- когда исключение-декларации исключение обработчик (пункт 15) объявляет объект того же типа (за исключением cv-квалификация) как исключение объекта (15.1), операция копирования может быть опущенным путем обрабатывать исключение-декларации по псевдоним объект исключения, если значение программа останется неизменной, за исключением для выполнения конструкторов и деструкторы для объекта, объявленного исключение-декларация.
Примечание: выделено мной
пример оптимизация возвращаемого значения (RVO) функции, которые поддерживает ваш компилятор.
конструктора не может вызывается при возврате по значению.
использовать -fno-elide-constructors
опция на GCC, чтобы отключить эту функцию.
кажется, это называется оптимизация возвращаемого значения.
Я предполагаю, что когда f()
возвращает C
object объект выделяется в пространстве стека вызывающего метода, поэтому для инициализации C a
. Это ваш default C called
.
C b = a
это вызывает конструктор копирования, следовательно, ваш CC called
.
кстати, пример на wiki выглядит очень похожим на ваш код.