Я могу вызвать конструктора копии явно?

Я немного смущен относительно механики конструктора копии. Исправьте меня, если я неправ:

Если метод берет ссылку на объект в качестве параметра, и класс определяет копию construtor, то класс использует конструктора для создания копии себя, и это передается функции вместо ссылки на исходный объект?

Кроме того, можно звонить

Object * obj = new Object(&anotherObject);

создать копию anotherObject?

16
задан Mehrdad Afshari 6 February 2010 в 17:15
поделиться

5 ответов

Нет, если функция принимает ссылку:

void f1( Object & o );   // call by reference

, то копирование не производится. Если функция принимает значение:

void f2( Object o );   // call by value

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

И да, когда вы говорите:

Object * obj = new Object(anotherObject);   // not &anotherObject

конструктор копирования используется явно (при условии, что anotherObject имеет тип Object.) Однако здесь нет ничего волшебного в использовании new - в данном случае :

Object obj2(anotherObject);

также используется конструктор копирования.

27
ответ дан 30 November 2019 в 16:30
поделиться

Если метод принимает ссылку на объект в качестве параметра , конструктор копирования не вызывается. Если бы это было так, то вызов самого конструктора копирования привел бы к бесконечному циклу (поскольку он принимает ссылку в качестве аргумента).

Эта строка не является допустимым способом вызова конструктора копирования. Он ожидает ссылку в качестве аргумента, а не указателя.

7
ответ дан 30 November 2019 в 16:30
поделиться

Конструктор копирования вызывается только при передаче по значению , а не по ссылке . По ссылке копирование не требуется (это часть того, для чего нужны ссылки!), поэтому конструктор копирования не вызывается.

1
ответ дан 30 November 2019 в 16:30
поделиться

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

Правила инициализации ссылки немного сложны, но суть в том, что если инициализатором является lvalue (аргумент в вызове метода в вашем случае) и тип ссылки такой же, как тип инициализатор (т.е. тип параметра совпадает с типом аргумента), тогда ссылка будет привязана напрямую. Т.е. копия не создается.

Object a; // class type
Object &r = a; // no copying
const Object &cr = a; // no copying

Если эти требования не выполняются (например, если инициализатором является rvalue), все зависит от ситуации. В некоторых случаях копирование может иметь место и будет иметь место. Например,

const Object &tr = Object();

может интерпретироваться компилятором как

const Object &tr = Object(Object(Object(Object())));

с конечным числом копий, зависящим от реализации. Конечно, из соображений эффективности компиляторы обычно стараются не создавать ненужных копий, даже если им разрешено копировать.

Классическим примером, который часто вызывает споры о допустимости копирующего поведения компилятора, является инициализация ссылки в выражениях, подобных приведенному ниже

Object a;
const Object &r = <some condition> ? a : Object();

Человек, знакомый с семантикой ссылок C ++, поймет, что выражения, подобные приведенным выше, скорее всего, являются обоснование стандартного разрешения на выполнение избыточного копирования во время инициализации ссылки.

3
ответ дан 30 November 2019 в 16:30
поделиться

Нет в обоих случаях. В первом случае передается ссылка на сам объект, и копия не создается. Во втором случае вы передаете указатель на конструктор объекта, поэтому копия не создается. Поэтому у объекта должен быть конструктор (не конструктор копии), что-то вроде object(anotherClass*)

1
ответ дан 30 November 2019 в 16:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: