Zugriff auf mehrere Interfaces über einzelnen Zeiger
-
Stimmt, SFINAE ist sonst nicht dabei. Danke für den Hinweis.
-
Wie sieht denn ein Aufruf in der TextView auf den Button aus?
-
Zum Beispiel folgendermassen.
myWidgetControllerundmyStringControllerwären die beiden Basisklassenzeiger. DieUpdate...()-Methoden werden bei Eigenschafts-Änderungen desButtonaufgerufen.void TextView::UpdateSize() { myText.SetSize(myWidgetController->GetSize()); } void TextView::UpdateString() { myText.SetString(myStringController->GetString()); myText.SetTextAlignment(myStringController->GetTextAlignment()); }
-
@Nexus: nur so ein Gedanke zwischendrin: Soweit ich mal in GUI-Frameworks reingesehen hab (mache sonst meist embedded-Software...), haben doch meist alle GUI-Klassen eine gemeinsame Wurzelklasse, sozusagen das Ur-GUI-Element. Dadurch sind sie alle über Pointer in einer Baumstruktur ansprechbar (so meine ich mich zu erinnern, dass es z.B. eine show( )-Methode gibt, kann sein bei QT oder .NET).
In Deinem Fall wäre das in etwa das, was
Widgetmachen soll, denn eine Position, Größe, Sichtbarkeit, "Aktiviertheit" oder so trifft doch auf die allermeisten GUI-Elemente zu, oder? Also könnte das doch in eine Basisklasse?Im Gegensatz dazu ist bei String nachvollziehbar, dass dies eine Spezialisierung ist, ganz klar.
-
Genau,
Widgetist diese Basisklasse. Wobei es noch weiter hinauf geht, wenn man elementare und Container-Komponenten unterscheidet. Doch alle elementaren GUI-Komponenten erben vonWidget.Vielleicht ist der Begriff "Interface" hier nicht ganz richtig, da es sich nicht immer um abstrakte, komplett statuslose Klassen handelt. Aber das Prinzip sollte klar sein.
-
Ich meinte es eher auf die Art, dass auch
StringAttributablevonWidgeterbt. In etwa so (bei mal angenommenen anderen "Attribut-Klassen" und Objektklassen wiePanelundTool):+-------------+ __________________| Widget | / +-------------+ / / | \ / / | \ | +------------+ +-----------+ +-----------+ | | StringAttr | | GraphAttr | | SoundAttr | | +------------+ +-----------+ +-----------+ | | \ | | | \ | +-------+ +--------+ +-------+ | Panel | | Button | | Tool | .... +-------+ +--------+ +-------+Die Attribut-Klassen erben virtuell von
Widget. Dadurch können die eigentlichen Objekt-Klassen von keinem (Panel), einem (Button) oder mehreren (Tool) der Attribute erben, ohne die Basisklasse mehrmals drin zu haben.Zugriff wäre wie folgt möglich:
1. Allgemeine Aufgaben wie show( )
Angenommen, es gäbe einenshow( )-Aufruf an alle Elemente.Widgetwürde die Methode virtuell deklarieren und die Unterklassen sie implementieren. Alle Objekte können über einenWidget*-Pointer angesprochen werden (wie z.B. vonTextView).ButtonoderToolwüßten ja, von welchen Klassen sie abgeleitet sind und rufen entsprechende Methoden ihrer Basisklassen auf. Dies wäre fürTextViewdann transparent.Oder:
2. Gezieltes Ansprechen von Elementen mit gleichen Attributen.
Da im Beispiel oben sowohlButtonals auchTooleinStringAttributablesind, können sie in einer Klasse TextView über einen Pointer von ebendiesem Typ referenziert werden. Das ist in etwa das, wie ich Deine Aufgabe von zu Beginn interpretiere. Gleichzeitig sind sie auchWidgets, d.h. Zugriff auf die Basisklasse ist ebenfalls möglich. Andere denkbare Klassen wie z.B.GraphViewwürden Objekte mitGraphAttributableansprechen usw.Kann sein, dass ich Deine Intention bzw. den Grund der weitestmöglichen Trennung der einzelnen Klassen noch nicht so ganz begriffen habe. Aber dieser Ansatz wäre etwas, was mir sowohl OO-mäßig als auch durch Cast-Vermeidung sinnvoll erscheint.
-
Vielen Dank für den Vorschlag, das tönt schon mal recht interessant. Virtuelle Vererbung habe ich bisher höchst selten verwendet, vielleicht hat sie noch ein paar interessante Tricks parat

Die Frage ist nun halt, ob
StringAttributablewirklich immer einWidgetist. Bei den bisherigen Beispielen schon, aber ob das so bleibt?Ich habe zum Beispiel gerade heute festgestellt, dass ich was grundsätzlich redesignen muss, um die Grösse einer GUI-Komponenten und die klickbare Fläche zu unterscheiden (z.B. bei
CheckBox). Mir ist dann sowas wieFloatRect GetClickableArea() consteingefallen, aber was mach ich bei Komponenten wie Scrollbars, die mehrere Klickflächen haben?
-
Ich habe letztens eine Socket-Klasse geschrieben, wo alles ein
Socketist.Sockethat die elementaren Methoden wie open( ), close( ), read( ), write( ). Davon virtuell abgeleitet auf der einen SeiteTCPundUDP, auf der anderenServerundClient. Darunter dann die eigentlichen TCPServerSocket, UDPClientSocket usw., die also von je zwei "Attributen" erben.
Bislang sind es immerSocketsgeblieben...Wenn man hierbei in der ersten Ebene nicht virtuell vererbt, haben die Attribute jeweils die Basisklasse drin und auf der unteren Ebene hat man diese dann doppelt.
Ist eigentlich ganz einfach: Man deklariert nur (in Deinem Fall)
class StringAttributable : virtual public WidgetBezüglich der Scrollbars: Naja, ein Scrollbar könnte ja wiederum z.B. aus mehreren einzelnen Elementen bestehen. Die haben alle
GetClickableArea( ), und die Bar sammelt die zusammen und gibt das alsGetClickableArea( )zurück.
-
minastaros schrieb:
Ich habe letztens eine Socket-Klasse geschrieben, wo alles ein
Socketist.Sockethat die elementaren Methoden wie open( ), close( ), read( ), write( ). Davon virtuell abgeleitet auf der einen SeiteTCPundUDP, auf der anderenServerundClient. Darunter dann die eigentlichen TCPServerSocket, UDPClientSocket usw., die also von je zwei "Attributen" erben.
Bislang sind es immerSocketsgeblieben...Bei solchen Designs muss man halt aufpassen, weil die Anzahl Klassen explodieren kann. Zumindest mag ich mich noch erinnern, dass Alexandrescu in Modern C++ Design sowas als Motivationsbeispiel für Policies genommen hat.

Aber die Idee mit virtueller Vererbung ist wirklich mal eine Überlegung wert.
minastaros schrieb:
Bezüglich der Scrollbars: Naja, ein Scrollbar könnte ja wiederum z.B. aus mehreren einzelnen Elementen bestehen. Die haben alle
GetClickableArea( ), und die Bar sammelt die zusammen und gibt das alsGetClickableArea( )zurück.Ja, so könnte ich es machen. Ähnlich wie beim
Panel, das andere GUI-Komponenten beinhaltet. Naja, bis ich zur Scrollbar-Implementierung komme, vergeht eh noch einige Zeit.
-
weil die Anzahl Klassen explodieren kann.
Das hielt sich aufgrund der vier Varianten noch in Grenzen, aber stimmt, die vermehren sich wie die Katzen...
Nexus schrieb:
Zumindest mag ich mich noch erinnern, dass Alexandrescu in Modern C++ Design sowas als Motivationsbeispiel für Policies genommen hat.

Richtig, aber das Buch wohnt erst seit einer Woche auf meinem Sofa bzw. Nachttisch. Habe immerhin schon Kapitel 1 durch, für die Sockets war es schon zu spät. Für die Templates fehlt mir noch die Erfahrung.