Ich habe eine rautenförmige Hierarchie von Klassen, in denen es weder einen Standardkonstruktor noch Kopierkonstruktoren gibt. Die beiden Konstrukteure ich habe, sind eine „Bewegung“ ein und eine andere, die einen L-Wert-Referenz auf ein Objekt nimmt:Wie implementiert man einen Move-Konstruktor für eine diamantförmige Vererbung?
struct base {
base(base&&) = default;
base(member_type&& m): member_(std::move(m)) {}
member_type member_;
};
struct virt_1: virtual base {
virt_1(virt_1&& rhs): base(std::move(rhs)) {}
virt_1(member_type&& m): base(std::move(m)) {}
};
struct virt_2: virtual base {
virt_2(virt_2&& rhs): base(std::move(rhs)) {}
virt_2(member_type&& m): base(std::move(m)) {}
};
struct concrete: virt_1, virt_2 {
concrete(concrete&& rhs) // ???
};
Neben keinen rautenförmigen Hierarchie verwendet wird, ist es möglich, die Bewegung Konstruktor für die konkrete Klasse zu implementieren ?
Danke!
Klingt sehr fehleranfällig für mich. Der Konstruktor der virtuellen Basis wird von der am weitesten abgeleiteten Klasse aufgerufen, und es sollte keinen Grund geben, warum er keinen Verschiebungskonstruktor aufrufen konnte. Aber jede weitere Ableitung, und es besteht eine gute Chance, dass jemand es vergessen wird, oder es falsch macht. Als allgemeine Regel sollten virtuelle Basisklassen keine Daten enthalten oder zumindest andere Konstruktoren als einen Standardkonstruktor haben, um solche Probleme zu vermeiden. –
@JamesKanze Ich bin mir bewusst, dass "Basis" sollte keine Daten enthalten, oder zumindest einen Standardkonstruktor, aber es kann nicht der Fall in meinem Kontext sein. Gibt es jedoch eine Möglichkeit, dass der Compiler sich beschweren wird, wenn jemand vergisst, den Konstruktor der virtuellen Basis aufzurufen, wenn er weiter ableitet? – piwi
@piwi, nein, es gibt keine Chance, weil 'base' keinen Standardkonstruktor hat, also muss der am meisten abgeleitete Typ ** es explizit konstruieren –