Скопировать конструкцию и оператор присваивания в производном классе

0

У меня есть класс (класс A), который наследует другой класс (класс B).

class A: public B

Класс B отключен копировать конструкцию и оператор присваивания (из-за того, что не допускается копирование).

private:
 B(const B&);
 B& operator=(const B&);

Мой вопрос заключается в том, что я должен также отключить операцию копирования и оператора присваивания в производном классе, или это нормально, если я не определял их обоих.

Теги:
copy-constructor
derived-class
assignment-operator

3 ответа

1
Лучший ответ

Вопрос скорее в том, следует ли его снова включить. Если какая-либо база или член не подлежит копированию, ваш класс по умолчанию будет недоступен для копирования. Как правило, вы не захотите удалить его, потому что это будет трудно или невозможно дать ему разумную семантику. Но есть заметные исключения: если базовый класс является абстрактным, например, вы можете включить конструктор копирования (но не присваивание) в производном классе для поддержки клонирования.

  • 0
    Если у меня есть переменная-указатель в производном классе, я получил предупреждение о том, что мне нужно определить конструкцию копирования и оператор присваивания. Должен ли я рассмотреть другое решение (т.е. без какого-либо указателя)? или это нормально, если я определю их и отключу, а также в производном классе?
  • 0
    @AvbAvb Если копирование и назначение были отключены в базовом классе и не включены повторно, предупреждение просто неверно. Я бы выключил его (и, возможно, пожаловался бы продавцу компилятора).
3

Подклассы должны иметь одинаковые или более строгие [предварительные условия, почтовые условия и инварианты], чем их родительские классы. Это Принцип замещения Лискова. Таким образом, вы не должны повторно включать построение копирования и т.д. И т.д. В производном классе, так как вы будете ослаблять контракт базового класса.

Если вы обнаружите, что вам нужно это сделать (или действительно хотели бы это сделать), то это может быть признаком того, что вам нужно переосмыслить свой дизайн.

  • 0
    Я не хочу их снова включать. Я просто спрашиваю, должен ли я также отключить их в производном классе или это нормально, если я ничего не делаю в производном классе.
  • 0
    Извините, я предположил, что вы уже знали, что поведение по умолчанию состояло в том, что производный класс "наследовал" контракт базового класса с точки зрения построения и назначения копии. Было бы яснее, если бы вы явно указали свое намерение, например: «Я хочу, чтобы у Derived были те же ограничения, что и у Base, что мне делать в Base?», На что я бы ответил «Ничего». все хорошо.
0

Отказ от копирования-конструктор и оператор присваивания базового класса приведет к тому, что оператор-конструктор и оператор присваивания производного класса также не будут использоваться:

class B {
public:
    B() { }
private:
    B(const B&);
    B& operator=(const B&);
};

class A : public B { };

В этом случае вам не нужно явно запрещать их для производного класса, так как реализация по умолчанию должна сначала использовать родительскую реализацию. Поэтому, если вы не пытаетесь получить доступ к ним в своем коде:

int main() {
    A a;
}

это будет совершенно справедливо. Однако, если вы попытаетесь скопировать:

int main() {
    A a;
    A a2 = A(a);
}

компилятор будет жаловаться на класс A пытающийся получить доступ к закрытым членам B (однако семантически второй сценарий не должен происходить).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню