Ответ 1
В [class.copy]:
Если определение класса
X
явно не объявляет конструктор перемещения, оно будет объявлено неявно как дефолт, если и только если (9.1) - X не имеет объявленного пользователем конструктора копирования,
(9.2) - X не имеет объявленного пользователем оператора назначения копирования,
(9.3) - X не имеет объявленного пользователем оператора назначения перемещения и (9.4) - X не имеет объявленного пользователем деструктора.
[Примечание: когда конструктор перемещения неявно не объявлен или явно указан, выражения, которые в противном случае мог бы вызвать конструктор перемещения, может вместо этого вызвать конструктор копирования. -end note]
Interface
имеет объявленный пользователем деструктор, поэтому конструктор перемещения Interface
не будет объявлен неявным образом как дефолт. Но A
не соответствует ни одной из этих точек пули, поэтому будет иметь неявный конструктор перемещения, который по умолчанию. A(A&& )
просто скопирует часть Interface
в соответствии с примечанием. Мы можем проверить это, добавив члены в Interface
и A
:
#include <iostream>
template <char c>
struct Obj {
Obj() { std::cout << "default ctor" << c << "\n"; }
Obj(const Obj&) { std::cout << "copy ctor" << c << "\n"; }
Obj(Obj&&) { std::cout << "move ctor" << c << "\n"; }
};
struct Interface {
virtual void myFunction() = 0;
virtual ~Interface() {};
Obj<'I'> base;
};
struct A : public Interface {
void myFunction() override {};
Obj<'A'> derived;
};
int main() {
A a1; // default I, default A
std::cout << "---\n";
A a2(std::move(a1)); // copy I, move A
std::cout << "---\n";
A a3(a2); // copy I, copy A
}