Можно ли явно вызвать конструктор копирования?

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

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

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

Object * obj = new Object(&anotherObject);

создать копию другого объекта?

Ответы

Ответ 1

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

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

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

Ответ 2

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

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

Ответ 3

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

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

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();

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

Ответ 4

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

Ответ 5

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

Ответ 6

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

Object dstObject;
new(&dstObject) Object(&anotherObject);