У меня есть куча вопросов, связанных с этим, я не мог найти точных ответов.
Класс A является основным классом, а B является подклассом
Если A :: operator = (const A & иное) было определено, копирует ли реализация по умолчанию B :: operator = члены B, затем вызывает A :: operator =?
Если был определен конструктор копирования, то будет ли реализация по умолчанию конструктора копирования для B копировать конструирует членов B, а затем вызывает конструктор копирования?
Нужно ли определять вышеупомянутые виртуальные функции в A, чтобы получить такое поведение? (Я полагаю, да для оператора = и нет для конструктора копирования, так как виртуальные конструкторы — нонсенс?)
Могу ли я запретить перегрузку оператора присваивания или конструктора копирования для подклассов A, чтобы принудительно использовать реализации по умолчанию?
Идея заключается в том, чтобы предложить API плагинов для моих пользователей. Мне нужно, чтобы API был C ++, так как скрипты слишком медленные (я попробую JIT-компиляцию однажды), но это должно быть очень просто.
Если по умолчанию оператор копирования-присваивания класса B
не удаляется, [class.copy] / 28
Неявно определенный оператор присваивания копирования / перемещения для класса без объединения
X
выполняет для каждого элемента копирование / перемещение назначения подобъектов. Прямые базовые классыX
назначаются первыми в порядке их объявления в базовый спецификатор-лист [Т.е. в том порядке, в котором они перечислены послеclass X : /*here*/ {/*...*/};
], а затем непосредственные нестатические члены данныхX
присваиваются в том порядке, в котором они были объявлены в определении класса.
Аналогично, [class.copy] / 15
Неявно определенный конструктор копирования / перемещения для класса X, не являющегося объединением, выполняет пошаговое копирование / перемещение своих баз и членов.
Порядок: сначала базовый класс (ы) (подобъекты базового класса), затем прямые нестатические члены данных, аналогично 1).
Для поведения, описанного в 1) и 2), нет. Виртуальные операторы присваивания вряд ли когда-либо пригодятся. Конструкторы могут вообще не быть виртуальными (не имеет смысла).
Для того, чтобы виртуальная функция в производном классе B
переопределить виртуальную функцию в базовом классе A
, он должен иметь одинаковые типы параметров. То есть вы могли бы иметь virtual A& operator=(A const&);
в базовом классе A
, но переопределить в классе B
должен был выглядеть как virtual B& operator=(A const&);
, который не оператор копирования-назначения для B
из-за типа параметра.
Не без «хаков». И вы на самом деле не перегружаете его, а скрываете все операторы присваивания базового класса. В противном случае это будет законно:
class A {};
class B { int i; };
A a;
B b = a; // using A::operator=(A const&)
Других решений пока нет …