Нет, это не нужно.
Если вы внимательно прочитаете Правило Три, вы заметите, что ничего не сказано о базовом классе, решение принимается исключительно на основе соответствующих атрибутов и поведения класса.
(проверьте этот пример на ideone)
#include <iostream>
struct A {
A(): a(0) {}
A& operator=(A const& rhs) { a = rhs.a; return *this; }
int a;
};
struct B: A { B(): b(0) {} int b; };
int main() {
B foo;
foo.a = 1;
foo.b = 2;
B bar;
bar = foo;
std::cout << bar.a << " " << bar.b << "\n";
}
// Output: 1 2
Это на самом деле истинная сила инкапсуляции . Поскольку вам удалось, используя Правило трех , настроить поведение базового класса sane , его производные классы не должны знать, является ли конструктор копирования по умолчанию компилятором или реализован вручную (и сложный), все, что имеет значение для пользователя (а производный класс является пользователем), заключается в том, что конструктор копирования выполняет копирование.
Правило трех напоминает нам о деталях реализации , помогающих достичь правильной семантики. Как и все детали реализации, это имеет значение только для разработчика и сопровождающего этого класса.