... автор заявляет, что конструктор копирования всегда вызывается, когда у вас есть заявление о форме
myClass myVar = 24;
Wrong.
Ваша книга была написана до того, как C++ 11 стал новым стандартом, поэтому не упоминается перемещение-семантика и возможность того, что может быть вызван конструктор перемещения . Более того, он не говорит о copy-elision. Да, это правда, что вызываемый экземпляр-конструктор может быть вызван, но из-за оптимизации, называемой copy-elison, компилятору разрешено удалять вызов из экземпляра copy/move-constructor. Это допускается, даже если это может повлиять на поведение программы, но обратите внимание, что это не гарантировано, которое должно произойти на каждом компиляторе.
Если вы пишете program, чтобы проверить это поведение, вы обнаружите, что не вызывается конструктор copy/move. Передача аргумента командной строки -fno-elide-constructors
disables этого разрешения и разрешает вызов от конструктора перемещения .
Форма инициализации вашей используемой называется копирования инициализации:
§ 8,5/15 Инициализаторы
инициализации, которая происходит в форме
T x = a;
, а также в , функция return, throwing exception (15.1), обработка исключения (15.3) и инициализация элемента агрегата (8.5.1) называется копирование-инициализация. [Примечание: Копирование-инициализация может вызвать движение (12.8).- конец примечание]
Предполагая, что копировать-Пропуск не происходит, то компилятор будет построить временный экземпляр класса для того, чтобы преобразовать указанный тип. Затем он будет копировать или перемещать-строить myVar
из этого временного использования с помощью конструктора-копии или move-constructor. Конструктор перемещения имеет приоритет над конструктором-копией для rvalues и будет вызываться только в том случае, если ваш класс имеет доступный конструктор перемещения; в противном случае вызывается конструктор копирования.
Если копирование не происходит, компилятор будет инициализировать myVar
, как если бы он был сконструирован с правой стороны. Это соответствует as-if rule, в котором говорится, что компилятор может выполнять оптимизации, учитывая, что он не влияет на наблюдаемое поведение.
Кроме того, он утверждает, что, когда у вас есть утверждения формы
myClass myVar;
myVar = 24;
то, что происходит на самом деле является то, что myClass
конструктор, который принимает целое число в качестве аргумента называется создать неназванный временную переменную тип myClass
, а затем вызывается оператор назначения . [...] Мой вопрос заключается в том, верны ли эти утверждения.
Да, конструкторы принимают участие в неявных преобразованиях типов. Из последнего проекта, N3797:
§ 12.3 Конверсия
Типа преобразование объектов класса может быть определены конструкторов и функциями преобразования. Эти преобразования называются определяемого пользователем преобразования и используются для неявного преобразования типа (пункт 4), для инициализации (8.5), так и для явного преобразования типа (5.4, 5.2.9)
Объяснение, которое ваш автор дал для этой части, было правильным, за исключением того, что оператор присваивания будет вызываться, если он доступен.
Невозможно сказать, не видя определения класса. – juanchopanza
Если 'myClass' имеет конструктор перемещения и оператор присваивания переадресации, то они будут использоваться –
Связанные: [Что такое трижды?] (Http://stackoverflow.com/questions/4172722/what-is- the-rule-of-three) –