2014-10-07 3 views
0

Я учусь о автоматического преобразования в Accelerated C++, а автор заявляет, что конструктор копирования всегда вызывается, когда у вас есть заявление о формеКонструктор копирования/Оператор присваивания

myClass myVar = 24; 

Кроме того, он утверждает, что, когда вы есть высказывания вида

myClass myVar; 
myVar = 24; 

что на самом деле происходит то, что конструктор MyClass, который принимает целое число в качестве аргумента называется создать неназванный временную переменную типа MyClass, а затем оператор присваивания называется , Думаю, книга была написана в 2000 году. Мой вопрос заключается в том, верны ли эти утверждения. Я узнал о конструкторе перемещения и переместил операции присваивания в другом месте, и мне было интересно, были ли эти вызовы вместо конструктора оператора/копии назначения.

Спасибо за ваше время. Я очень ценю это.

+2

Невозможно сказать, не видя определения класса. – juanchopanza

+1

Если 'myClass' имеет конструктор перемещения и оператор присваивания переадресации, то они будут использоваться –

+0

Связанные: [Что такое трижды?] (Http://stackoverflow.com/questions/4172722/what-is- the-rule-of-three) –

ответ

2

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

myClass myVar = 24; 

Wrong.

Ваша книга была написана до того, как C++ 11 стал новым стандартом, поэтому не упоминается перемещение-семантика и возможность того, что может быть вызван конструктор перемещения . Более того, он не говорит о copy-elision. Да, это правда, что вызываемый экземпляр-конструктор может быть вызван, но из-за оптимизации, называемой copy-elison, компилятору разрешено удалять вызов из экземпляра copy/move-constructor. Это допускается, даже если это может повлиять на поведение программы, но обратите внимание, что это не гарантировано, которое должно произойти на каждом компиляторе.

Если вы пишете program, чтобы проверить это поведение, вы обнаружите, что не вызывается конструктор copy/move. Передача аргумента командной строки -fno-elide-constructorsdisables этого разрешения и разрешает вызов от конструктора перемещения .

Форма инициализации вашей используемой называется копирования инициализации:

§ 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)

Объяснение, которое ваш автор дал для этой части, было правильным, за исключением того, что оператор присваивания будет вызываться, если он доступен.

+0

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

+0

AC++ - хорошо расцененная книга, я подозреваю, что фактический текст (который перефразирует OP) позволит копировать эликсир –

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