У меня есть класс (класс A), который наследует другой класс (класс B).
class A: public B
Класс B отключен копировать конструкцию и оператор присваивания (из-за того, что не допускается копирование).
private:
B(const B&);
B& operator=(const B&);
Мой вопрос заключается в том, что я должен также отключить операцию копирования и оператора присваивания в производном классе, или это нормально, если я не определял их обоих.
Вопрос скорее в том, следует ли его снова включить. Если какая-либо база или член не подлежит копированию, ваш класс по умолчанию будет недоступен для копирования. Как правило, вы не захотите удалить его, потому что это будет трудно или невозможно дать ему разумную семантику. Но есть заметные исключения: если базовый класс является абстрактным, например, вы можете включить конструктор копирования (но не присваивание) в производном классе для поддержки клонирования.
Подклассы должны иметь одинаковые или более строгие [предварительные условия, почтовые условия и инварианты], чем их родительские классы. Это Принцип замещения Лискова. Таким образом, вы не должны повторно включать построение копирования и т.д. И т.д. В производном классе, так как вы будете ослаблять контракт базового класса.
Если вы обнаружите, что вам нужно это сделать (или действительно хотели бы это сделать), то это может быть признаком того, что вам нужно переосмыслить свой дизайн.
Отказ от копирования-конструктор и оператор присваивания базового класса приведет к тому, что оператор-конструктор и оператор присваивания производного класса также не будут использоваться:
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
(однако семантически второй сценарий не должен происходить).