Почему аргументом конструктора копирования является ссылка, а не указатель?
Почему мы не можем использовать указатель вместо этого?
Почему аргументом конструктора копирования является ссылка, а не указатель?
Почему мы не можем использовать указатель вместо этого?
Существует много причин:
Ссылки не могут быть NULL. ОК, возможно создать ссылку NULL, но также можно отличить std::vector<int>*
от std::vector<SomeType>*
. Это не означает, что такой актер определил поведение. И также не создает ссылку NULL. Указатели определили поведение, когда установлено значение NULL; ссылок нет. Поэтому ссылки всегда должны ссылаться на фактические объекты.
Переменные и временные файлы не могут быть неявно преобразованы в указатели на их типы. По понятным причинам. Мы не хотим, чтобы указатели на время работали, поэтому стандарт явно запрещает это делать (по крайней мере, когда компилятор может сказать, что вы это делаете). Но нам разрешено иметь ссылки на них; они неявно созданы.
Из-за точки 2, использование указателей, а не ссылок потребует, чтобы каждая операция копирования использовала адрес-оператора (&). О, подожди, комитет C++ по глупости допустил перегрузку. Таким образом, любая операция копирования должна будет использовать std::addressof
, функцию С++ 11, чтобы получить адрес. Поэтому каждая копия должна выглядеть как Type t{std::addressof(v)};
Или вы могли бы просто использовать ссылки.
Это просто номенклатура. Вы также можете использовать указатель, но это можно назвать конструктором преобразования.
Если вы думаете об этом, это имеет смысл, потому что вы копируете один объект в другой (ergo the "copy" ). Не от указателя к объекту. Если бы это был указатель, он не сделал бы копию, потому что вы не копируете указатель на объект, а скорее объект, на который указывает указатель на ваш объект.
Потому что это отклоняется стандартом.
Цитата из проекта стандарта С++ n3376 - раздел 12.8.2:
Конструктор без шаблона для класса X является конструктором копирования, если его первый параметр имеет тип X &, const X &, летучие X & или const volatile X &, и либо нет других параметров, либо все остальные параметры имеют аргументы по умолчанию
Почему это должен быть указатель? Нулевой указатель не имеет смысла. И использование указателя не позволит копировать временные файлы, так что вы не мог делать такие вещи, как:
MyClass
func()
{
// ...
return MyClass(...);
}
Вы можете определить конструктор с указателем. Но это не будет быть конструктором копии, поскольку он не может использоваться в таких случаях, как вышесказанное. И это не будет препятствовать компилятору генерировать конструктор копирования.
Поскольку указатель может быть nullptr
, который должен быть проверен, и временные файлы не могут иметь указателей на них.
Передача по ссылкам гарантирует, что фактический объект передается конструктору копирования, в то время как указатель может иметь значение NULL и сделать конструктор неудачным