Lassen Sie mich Ihnen das Problem sagen, das ich habe. Ich entwerfe eine Reihe von Klassen, um ein digitales Gerät zu steuern. Dieses Gerät kann in zwei Betriebsmodi arbeiten. In dem ersten Modus kann er einen spezifischen Satz von Operationen ausführen, und in dem zweiten Modus kann er einen weiteren Satz von Operationen durchführen (mit möglicherweise einigen gemeinsamen Operationen zwischen den beiden). Ich kann auch den Modus des Geräts im Lauf ändern, damit ich bei Bedarf zwischen den beiden Modi wechseln kann. Unabhängig vom Modus verwendet das Gerät den gleichen Satz von Registern.C++ mehrfache Vererbung von Basisklassen mit Mitgliedern mit demselben Namen
Ich dachte in Lösung dieses Problem mit einer Basisklasse für jeden Modus, so kann ich Objekte von Modus 1 haben, wenn ich die erste Reihe von Operationen und Objekte von Modus 2 brauche, wenn ich die zweite Reihe von Operationen benötigen. Dann könnte ich eine Klasse aus diesen beiden Basisklassen ableiten, so dass ich Objekte haben kann, die alle Operationen ausführen.
Das Problem mit meinem Design ist, dass die beiden Basisklassen einige gemeinsame Funktionen und Verweise auf die gleichen Register haben. Da ich die Vererbung von Mitgliedern nicht verhindern kann, würde ich in der abgeleiteten Klasse Duplikate haben. Ich weiß, ich kann wählen, welches Duplikat mit dem Scope-Operator zugreifen soll, aber ich denke immer noch, dass dies ein schlechtes Design ist.
Meine Frage ist also: Gibt es eine idiomatische Lösung dieses Problems?
Wenn es keine richtige oder einfache Möglichkeit gibt, dies zu lösen, denke ich über Design 3 hierarchisch unabhängig Klassen. Ich hätte einen doppelten Code, aber das ist kein großes Problem, oder?
Code (vereinfacht) zur Erläuterung:
class mode1
{
protected:
volatile uint8_t& reg1;
volatile uint8_t& reg2;
uint8_t data;
public:
virtual void operation1() final { // do something }
virtual void operation2() final { // do something }
virtual void operation3() final { // do something }
};
class mode2
{
protected:
volatile uint8_t& reg1;
volatile uint8_t& reg2;
uint8_t data;
public:
virtual void operation4() final { // do something }
virtual void operation2() final { // do something }
virtual void operation5() final { // do something }
};
class mode1and2 : public mode1, public mode2
{
public:
void operation6() { // do something }
void operation7() { // do something }
};
Note-Modi 1 und 2 haben operation2 und alle Datenelemente gemeinsam haben.
Warum möchten Sie ein Objekt, das alle Operationen ausführt? – immibis
Was hast du probiert? – Raindrop7
Werfen Sie einen Blick auf virtuelle Vererbung. –