Это именно так, как вы сказали.
Когда вы передаете объект по значению, его конструктор копирования вызывается для создания нового экземпляра такого объекта, который будет использоваться внутри функции. Изменения, внесенные в такой новый объект, не будут отражены в исходном 1 .
Как и в случае со структурами, конструктор копирования по умолчанию просто делает поверхностную копию исходного объекта, то есть его поля копируются 2 в новый экземпляр; во многих случаях это нежелательно (например, если объект оборачивает указатель / другой ресурс), поэтому существуют классы, которые переопределяют конструктор копирования или полностью его отключают. Объекты этих последних классов могут передаваться только по указателю или по ссылке.
Передача объектов по значению может быть дорогостоящей, если они больше указателя (по размеру) или вообще, если их конструктор копирования не «дешев». С другой стороны, по сравнению с указателями передача по значению дает обычные преимущества, заключающиеся в том, что нет необходимости указывать владение указателем, позволяя вызываемому объекту делать с объектом все, что ему нужно, и т. Д.
Обратите внимание, что передача объекта по значению убивает полиморфизм. Это потому, что функция, получающая объект по значению, получает статически типизированный объект с точным размером и типом, поэтому любая попытка передать объект производного класса приведет к нарезке объекта (вызывается конструктор копирования для базового класса, который по умолчанию просто копируются поля, доступные в базовом классе).
Это причина, по которой часто предпочитаемый метод передачи объектов - это const
ссылка. Это дает несколько преимуществ:
- копий не было; объект, который увидит вызывающий, будет точно тем, который указан в момент вызова;
- невозможно внести изменения в исходный объект, благодаря квалификатору
const
;
- если, однако, вызываемый объект должен изменить копию объекта, он все равно может создать копию самостоятельно из ссылки;
- нет синтаксиса неуклюжего указателя;
- полиморфизм сохранен, поскольку за кадром мы фактически передаем указатель;
- нет больших сомнений относительно владения объектами: общее правило относительно ссылок заключается в том, что они принадлежат вызывающей стороне.
<ч />
Что касается "необработанных полей" объекта; естественно, если исходный объект и копия продолжают совместно использовать указатель / дескриптор одного и того же ресурса, некоторые модификации одного могут повлиять на другой.
Примитивные типы (и в общем случае POD) копируются по битам, в то время как конструктор копирования вызывается для типов, не относящихся к POD.