В соответствии со стандартом С++ класс, имеющий виртуальные функции, не может иметь тривиальный конструктор копирования:
Конструктор копирования/перемещения для класса X тривиален, если он не предоставляется пользователем и если
- класс X не имеет виртуальных функций (10.3) и виртуальных базовых классов (10.1) и
- конструктор, выбранный для копирования/перемещения каждого подобъекта прямого базового класса, тривиален и
- для каждого нестатического элемента данных X, относящегося к типу класса (или его массиву), конструктор, выбранный для копирования/перемещения этого элемента, тривиален;
в противном случае конструктор copy/move не является тривиальным.
Теперь представьте себе иерархию классов, которая удовлетворяет всем упомянутым условиям, кроме условия "нет виртуальных функций":
struct I
{
virtual void f() = 0;
};
struct D final : I
{
void f() override
{
}
};
С точки зрения реализации эти классы содержат только указатель на таблицу виртуальной диспетчеризации. И базовый класс не имеет никаких объявленных пользователем конструкторов, а производный класс является окончательным, поэтому указанный указатель всегда может иметь постоянное значение. Учитывая все это, конструктор копирования может быть тривиальным, но стандарт явно запрещает рассматривать его как таковой.
С другой стороны, выполняются условия обработки таких классов, как тривиально разрушаемые. Класс не объявляет виртуальный деструктор и использует неявно определенные деструкторы.
Требование тривиальности деструкторов выглядит как указание на оптимизацию - неявно определенные деструкторы не должны восстанавливать указатели на виртуальную таблицу в этом случае.
Но такая оптимизация идет на полпути, на мой взгляд; классы с виртуальными функциями по-прежнему не могут быть сняты, даже если они могут быть уничтожены тривиально.
Вопросы:
-
Есть ли какие-либо причины, о которых я не думал с точки зрения реализации, почему у таких классов должны быть нетривиальные конструкторы-копии?
-
Есть ли какие-либо причины, ограничения в тривиальности для конструкторов-копий не могут быть смягчены в стандарте?