Конструктор копирования в С++ вызывается, когда объект возвращается из функции?

Я понимаю, что конструктор копирования вызывается в трех экземплярах

  1. При создании экземпляра одного объекта и его инициализации значениями из другого объекта.
  2. При передаче объекта по значению.

<сильный>3. Когда объект возвращается из функции по значению.

У меня есть вопрос с номером 3, если конструктор копирования вызывается при возврате значения объекта, не должен ли он создавать проблемы, если объект объявлен локально в функции.

я имею в виду, что конструктор копирования является глубоким копированием и принимает ссылку на объект в качестве параметра


person Kazoom    schedule 20.03.2009    source источник
comment
Не гарантируется, что в этих случаях будет вызван конструктор копирования, потому что стандарт C++ позволяет компилятору в определенных случаях оптимизировать копирование — в частности, оптимизация возвращаемого значения   -  person rmp251    schedule 30.10.2013
comment
Ссылка, указанная @rmp251, четко отвечает на этот вопрос.   -  person Jingguo Yao    schedule 21.11.2016


Ответы (5)


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

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

person sharptooth    schedule 20.03.2009

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

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

person unwind    schedule 20.03.2009
comment
я понимаю, что когда значение объекта возвращается, он сначала вызывает конструктор копирования, но конструктор копирования определяется пользователем, он принимает ссылку как параметр ClassA (const ClassA&), что в этом случае произойдет? что произойдет, если вы просто вернете ссылку вместо значения, исходя из вашей логики - person Kazoom; 20.03.2009
comment
Если функция объявлена ​​как возвращающая ссылку, возвращающая ссылку на локальную переменную, это большой запрет. Вы вернете ссылку на объект, который будет отброшен при выходе из функции. Использование этой ссылки, вероятно, вызовет проблемы, в том числе столкновение. - person sharptooth; 20.03.2009
comment
да, я понимаю это, поэтому, когда конструктор копирования, который принимает ссылку в качестве параметра, вызывается при возврате значения, что произойдет? тоже не должно падать? - person Kazoom; 20.03.2009
comment
В чем проблема? Функция вот-вот вернется. Вызывается конструктор копирования. Он принимает ссылку на локальную переменную. Он использует эту ссылку для копирования всего в новый объект, который будет использоваться в качестве возвращаемого значения. - person sharptooth; 20.03.2009

Согласно ответу на мой вопрос, конструктор копирования < em>может вызываться даже дважды: один раз, чтобы скопировать локальный объект в возвращаемый «объект», и один раз, чтобы скопировать возвращаемый объект в переменную, которой он был назначен.

Однако не обязательно быть! Компилятор может оптимизировать обе конструкции копирования.

person xtofl    schedule 20.03.2009
comment
Я не согласен с вами. Конструктор копирования вызывался только один раз для возвращаемого объекта, при назначении возвращаемого объекта другому объекту внешней области вызывается оператор присваивания, а не конструктор копирования. - person Peiti Li; 13.02.2013
comment
@PeitiPeterLi - действительно, компилятор может выполнять любой уровень оптимизации, мой g++ пропустил оба конструктора копирования для этого оператора myClass Obj=makeObj(10); здесь makeObj() инициализирует объект значением 10 и возвращает значение. (это не задание) - person saumitra mallick; 06.07.2018

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

person Lou Franco    schedule 20.03.2009
comment
но что, если конструктор копирования принимает ссылку в качестве параметра (глубокая копия), в этом случае он не будет копировать весь объект, верно? - person Kazoom; 20.03.2009
comment
Зависит от конструктора копирования. По умолчанию используется конструкция копирования по элементам. Обычно вы должны реализовать свой конструктор копирования, чтобы не полагаться на время жизни переданного объекта. Вам не нужно выполнять глубокое копирование, но вам нужно убедиться, что общие данные остаются. - person Lou Franco; 20.03.2009

Есть три общих случая, когда вызывается конструктор копирования:

  1. При создании экземпляра одного объекта и его инициализации значениями из другого объекта (того же типа).
  2. При передаче объекта по значению.
  3. Когда объект возвращается из функции по значению.
person Bilal Qureshi    schedule 22.04.2013