Копировать конструкторы - С++
Можно ли написать конструктор копирования, просто передав указатель вместо ссылки на const? (Было бы хорошо, если бы я удостоверился, что я не собираюсь менять какие-либо значения?)
Так же:
SampleClass::SampleClass(SampleClass* p)
{
//do the necessary copy functionality
}
вместо:
SampleClass::SampleClass(const SampleClass& copyObj)
{
//do the necessary copy
}
Спасибо заранее.
Спасибо всем. Итак, если я напишу конструктор, который принимает указатель (и думал, что мой конструктор копирования), компилятор по-прежнему будет снабжать конструктором копии по умолчанию, и в этом случае мой конструктор (который, как я думал, был моим конструктором копирования) не будет вызываться и будет вызываться конструктор копии по умолчанию. Получил это.
Ответы
Ответ 1
Да, вы можете написать конструктор, который принимает указатель на объект. Однако его нельзя назвать конструктором копирования. Само определение конструктора копирования требует, чтобы вы передавали объект того же класса. Если вы передаете что-либо еще, да, это конструктор в порядке, но не конструктор копирования.
Ответ 2
Вы можете написать конструктор, который принимает указатель в качестве аргумента.
Но конструктор копирования - это имя, которое мы даем конкретному конструктору.
Конструктор, который принимает ссылку (предпочтительно const, но не обязательно) того же класса, что и аргумент, просто назван конструктором копирования, потому что это то, что он эффективно делает.
Ответ 3
Помимо того факта, что это не будет конструктор копирования, и компилятор сгенерирует конструктор копирования, если вы явно не отключите его, нет ничего, что можно было бы получить и многое потерять. Какова правильная семантика для конструктора из нулевого указателя? Что это добавляет пользователю вашего класса? (Подсказка: ничего, если она хочет построить из объекта кучи, она может просто разыменовать указатель и использовать обычный конструктор копирования).
Ответ 4
Нет. Конструкторы копирования должны использовать ссылку, а не указатель, если это полезно для передачи по значению и т.д.
Ответ 5
По определению копия ctor использует ссылку const. Хотя нет ничего, что мешает вам писать ctor, который принимает указатель, он вызывает некоторые проблемы, которые не возникают при использовании ссылки - например, что должно/может произойти, если пустым указателем передано?
Ответ 6
Конструктор копирования нуждается в ссылке, потому что для параметра значения потребуется создать копию, которая вызовет конструктор копирования, который сделает копию его параметра, который будет ссылаться на конструктор копирования, который...
Ответ 7
Вы можете написать такой конструктор, но это не технически конструктор копирования. Например, контейнеры STL по-прежнему будут использовать созданный компилятором конструктор копий (компилятор генерирует его, потому что вы его не пишете).
Ответ 8
Конструктор копирования неявно используется в двух случаях:
- Когда экземпляр вашего класса передается по значению функции.
- Когда экземпляр вашего класса возвращается значением из функции.
Как уже упоминалось, вы можете написать конструктор с описанной сигнатурой (или с указателем const), но он не будет использоваться ни в одном из указанных случаев.
Ответ 9
Вы можете написать вполне допустимый конструктор копирования и по-прежнему иметь возможность передавать ссылку NULL. Вы можете проверить значение NULL, но только если вы не используете списки инициализации конструктора.
Пример:
MyClass::MyClass( MyClass const& MyClassCopy )
: somevar( MyClassCopy.somevar ) // <- the init list goes here.
{
// If MyClassCopy is NULL, the initialization above is doomed!
// However we can check for NULL in the constructor body but
// the initialization list must be removed ...
if (&MyClassCopy == NULL ) throw( std::runtime_error("NULL pointer!"));
somevar = MyClassCopy.somevar;
}
// I'll now do some very dangerous programming to
// demonstrate one way that a NULL can get through ...
MyClass* P = NULL;
MyClass A( *P ); // Bang, you're dead!
Насколько я знаю, нет способа проверить NULL из списка инициализации, поэтому, если вы думаете, что можете получить ситуацию, когда NULL проходит, вам нужно проверить его в теле конструктора и выполните инициализацию оттуда.
Не забывайте, что есть несколько ошибок с функцией:: operator =(), чтобы знать...