Как использовать по умолчанию и собственный конструктор копирования в C ++?

У меня длинный урок с большим количеством участников. Я хочу написать конструктор копирования для него. Но если я напишу свой собственный конструктор копирования, я потерял доступ к конструктору по умолчанию.

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

Есть ли возможность получить доступ к конструктору копирования по умолчанию, когда уже есть мой собственный конструктор копирования?

8

Решение

Оберните вещи, которые вы не хотите изменять, в структуру и извлекайте из нее (в частном порядке). В вашем конструкторе копирования просто вызовите конструктор копирования вашего базового класса.

11

Другие решения

Нет, вы не можете иметь как по умолчанию, так и свой собственный экземпляр c-tor.

Но есть два обходных пути с этой проблемой:


1 Заключите ваши указатели в некоторый класс с определенной семантикой копирования

Пример:

class A {
public:
private:
int trivial1;
int trivial2;
...
SomePointer  nontrivialMember;
};

class SomePointer {
public:
SomePointer(const SomePointer&); // here the non trivial part of A copy semantics
int* nonTrivialMember;
};

2 Заключите тривиальные параметры в некоторую тривиальную структуру

Пример:

class A {
public:
A(const A& o) : data(o.data) {
// non trivial part
}
private:
struct Data {
int trivial1;
int trivial2;
...
} data;
int* nontrivialMember;
};

Я бы всегда выбрал первое решение.

[ОБНОВИТЬ]

Существует также третье решение, очень похожее на мое второе, заключающее вашу тривиальную часть в частный унаследованный базовый класс. Я бы все же предпочел 1-е решение.

6

Простейшим подходом к этому было бы заключить указатели в классы, которые будут выполнятьремонт‘вручную в их конструкторе копирования, тогда вы можете с радостью использовать конструктор копирования по умолчанию.

3

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

0

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

void DeepCopy(MyClass* rhs);

Например.

0

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

Смотрите пример:

struct Data
{
int i;
std::string s;

Data(): i(), s() {}
};

class Code: private Data
{
public:

Code() {}

Code(const Code& rhs): Data(rhs) // Call default copy ctor
{
i = 42; // Your copy part
return *this;
}

};
0

Мое решение — простой memcpy () вместо невозможного вызова неявного (сгенерированного компилятором) конструктора копирования, как показано в примере ниже:

Class Foo
{
public:
...
Foo (Foo & other) {
// copies trivial part (and non-trivial part with possible wrong values)
memcpy(this, &other, sizeof(Foo));

// your non-trivial part here, overwrites the wrong values (if any) above.
}
}

Тем не менее, побочным эффектом является то, что memcpy () также скопирует эту нетривиальную часть, которая является пустой тратой. Если нетривиальная часть не содержит слишком много места, я предпочту свое решение.

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

Class Bar
{
int x, y, z;

// memcpy() wastes these 4 bytes copy,
// since actual copy constructor wants a new string
string *s;
}
0

Это сработало для меня … (C ++ 11, не знаю, работает ли оно на старых std)
Не уверен, почему это не заканчивается бесконечной петлей.

class Foo {
public:
Foo(const Foo &orig) {
*this = orig;
... exchange pointers, do own stuff
}
0
По вопросам рекламы [email protected]