Подтвердить что ты не робот

Копировать конструкторы - С++

Можно ли написать конструктор копирования, просто передав указатель вместо ссылки на const? (Было бы хорошо, если бы я удостоверился, что я не собираюсь менять какие-либо значения?)

Так же:

SampleClass::SampleClass(SampleClass* p)
{
 //do  the necessary copy functionality
}

вместо:

SampleClass::SampleClass(const SampleClass& copyObj)
{
//do the necessary copy
}

Спасибо заранее.


Спасибо всем. Итак, если я напишу конструктор, который принимает указатель (и думал, что мой конструктор копирования), компилятор по-прежнему будет снабжать конструктором копии по умолчанию, и в этом случае мой конструктор (который, как я думал, был моим конструктором копирования) не будет вызываться и будет вызываться конструктор копии по умолчанию. Получил это.

4b9b3361

Ответ 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 =(), чтобы знать...