Bietet Private-Vererbung irgendwelche Vorteile gegenüber Komposition?
-
Optimizer schrieb:
virtual void ProcessMessage(const Message&) = nullptr;Da ist auch nullptr erlaubt?
-
Optimizer schrieb:
Ich hab letztens private Vererbung hierfür eingesetzt:...
Alternativ könnte man überlegen, nicht nur Empfängerobjekte zu registrieren, die je nach Nachricht eine bestimmte virtuelle Funktion anbieten müssen, sondern beliebige Objekte/Methodenzeiger-Paare registrieren zu können.
-
DStefan schrieb:
Ich finde es nicht nachvollziehbar, sich im Falle privater Vererbung mit der Definition "IST-EIN" aufzuhalten und dann von diesem Standpunkt aus private Vererbung zu beurteilen.
Im Falle öffentlicher Vererbung halte ich IST-EIN für ein brauchbares Kriterium, bei privater Vererbung aber ist es Unsinn. Wie wäre es stattdessen mit IST-IMPLEMENTIERT-MIT (oder ähnlichem)?
Dann schon "IST-IMPLEMENTIERT-MIT-UND-FÜR-SICH-SELBST-UND-IM-KREISE-DER-FREUNDE-IST-EIN" - für sich selbst und für alle friends gilt nunmal die Ist-Ein-Beziehung. Und die wegzudiskutieren hilft auch nicht dagegen dass es semantisch eben etwas anderes ist als Aggregation.
DStefan schrieb:
Der Sinn von expose erschließt sich mir nicht. Was ist der Vorteil gegenüber der using-Lösung? Abgesehen halt vom IST-EIN-"Problem".
Eben. Abgesehn von der Typsicherheit kann man auch Makros an Stelle vieler Templates benutzen. Man kann für viele Schwächen der Sprache Workarounds finden, die super funktionieren auch wenn sie eigentlich was anderes bedeuten.
btw:
class E { A someA; A anotherA; public: expose someA.foo; expose anotherA.bar; };nicht machbar mit Vererbung

-
volkard schrieb:
Optimizer schrieb:
virtual void ProcessMessage(const Message&) = nullptr;Da ist auch nullptr erlaubt?
Ich hoffe es. Im Moment ist es nur ein #define.
-
Optimizer schrieb:
Ich hoffe es.
Du hast =0 gelernt, =0 steht im Standard, andere haben =0 gelernt.
Wozu abweichen? Purer Flagellantismus?Ganz verwundert bin über das rätselhafte =nullptr (oder =0x0). Wenn schon, dann mach
#define abstract =0dann hätte das noch ne lesbare Aussage.
noch besser:
virtual void ProcessMessage(const Message&) = 0; //abstract
-
Ich habe bisher immer so gedacht, = 0 wäre gedanklich der Weg, um nen Funktionspointer (was anderes ist der Name der Funktion ja nicht) ungültig sein zu lassen. Bisher war = 0 auch der Weg, um nullptr jeglicher Art zu erhalten.
Anscheinend ist aber auch weiterhin nur = 0 zulässig was ich etwas inkonsequent finde. Mit einem Integer eine nicht implementierte Funktion zu beschreiben, erscheint mir nicht logisch.
-
volkard schrieb:
noch besser:
virtual void ProcessMessage(const Message&) = 0; //abstractDer Trivialkommentar ist nicht besser, ich schreibe keine Kommentare für Leute, die C++ nicht grundsätzlich lesen können. Das ist für mich auf der selben Ebene wie:
int a = b + c; // here, we add b and c
-
Optimizer schrieb:
Mit einem Integer eine nicht implementierte Funktion zu beschreiben, erscheint mir nicht logisch.
Ja, man wollte halt nicht noch ein Schlüsselwort einführen, was ein wenig schade ist. Dieses =0 mit abstrakten Funktionen und abstrakten Basisklassen ist schon ein gewaltiger Brocken und hat mehr Zuwendung verdient.
-
In Hinsicht auf den neuen Standard würde ich -- wenn ich mich von 0 abwende -- wohl eher sowas machen:
#define abstract 0Dann bleibt man einheitlich gegenüber verbotenen und standardgenerierten Funktionen:
class MyClass { virtual void Foo() = abstract; MyClass() = default; MyClass& operator= (const MyClass&) = delete; };Obwohl ich das Schlüsselwort-Recycling ziemlich schlimm finde, vor allem bei
delete. Meines Erachtens sind mehr Schlüsselwörter besser als mehrdeutige, vor allem wenn die Anwendungsbereiche sich so stark wie hier unterscheiden (beistatickönnte man sich darüber streiten...).
-
<offtopic>
hast du nen link, wo beschrieben ist, was =delete oder =default bedeutet? oO
is iwie doof zu ergooglen - zumindest war ich zu unvermögend dazu ;o)
-
-
unskilled schrieb:
hast du nen link, wo beschrieben ist, was =delete oder =default bedeutet? oO
is iwie doof zu ergooglen - zumindest war ich zu unvermögend dazu ;o)Wie wärs mit einem Artikel aus dem C++-Magazin? Unter Punkt 2.7 findest du die beschriebenen Sprachmittel.
-
Nexus schrieb:
unskilled schrieb:
hast du nen link, wo beschrieben ist, was =delete oder =default bedeutet? oO
is iwie doof zu ergooglen - zumindest war ich zu unvermögend dazu ;o)Wie wärs mit einem Artikel aus dem C++-Magazin? Unter Punkt 2.7 findest du die beschriebenen Sprachmittel.
oh - danke - den artikel hab ich iwie noch nie gesehen, obwohl ich eigtl regelmäßig nach artikeln gesucht habe...
-
Nexus schrieb:
Obwohl ich das Schlüsselwort-Recycling ziemlich schlimm finde, vor allem bei
delete. Meines Erachtens sind mehr Schlüsselwörter besser als mehrdeutige, vor allem wenn die Anwendungsbereiche sich so stark wie hier unterscheiden (beistatickönnte man sich darüber streiten...).Ich finde es in dem Fall gar nicht mal so schlimm, weil ja kaum Verwechslungsgefahr besteht, da sie eben genau so unterschiedliche Anwendungsgebiete haben, aber das Schlüsselwort wirklich sehr genau aussagt, was passiert. Ich fände es verwirrender, wenn da neue, nicht ganz so passende Schlüsselwörter benutzt würden.
Natürlich macht es ein paar Sachen, wie z.B das Suchen nach der Funktionsweise (wie unskilled bereits schön gezeigt hat) einiges komplizierter, da es mehrdeutig ist. Auch können so Fragen, wie "was macht delete" nicht mehr so einfach beantwortet werden.
Aber ich denke, dass wenn man sich daran gewöhnt hat das einiges intuitiver zu benutzen ist, als wenn man ein Haufen Keywords mehr hat.
-
Ja, ist wohl alles ein wenig Gewohnheitssache. Ich finde einfach,
deletegehört zur Speicherverwaltung und hat in Memberfunktionsattributen nichts zu suchen. So genau wie du sagst passt es auch gar nicht: "to delete" bedeutet löschen. Vom Löschen einer Funktion zu reden halte ich nicht für besonders intuitiv. Meiner Ansicht nach wäre sowas wieforbiddenoder ähnlich treffender gewesen.Und wieso glaubst du, dass es hier komplizierter wäre, ein neues Schlüsselwort zu benutzen? Dann hätte man eine klare Trennung und würde nicht krampfhaft versuchen, das Freigeben von Speicherbereich mit dem Weglassen von Methoden zu assoziieren.
Anderes Beispiel fürs Keyword-Recycling:
enum class. Was hat denn bitte eine Enumeration mit einer Klasse zu tun?enum structhielte ich für besser, Struktur kann man noch allgemeiner interpretieren. Aber auch das ist nicht wirklich das Wahre.
-
Komplizierter meinte ich, dass man nicht krampfhat einen anderen Namen für etwas sucht, wenn der passende reicht. Sprich man sucht sich dann ein sehr ähnliches Wort, dass vielleicht in anderen Sprachen (z.B Deutsch) gar keinen Unterschied macht. Dann wäre es in dem Sinne komplizierter, dass man teils vor einer "Auswahl" steht, wo man dann jedes mal in die Falle tritt und das falsche Keyword nimmt.

(z.B erinnerst du dich bestimmt an das Beispiel von letzens mit count/size. genau solche Sachen meine ich).
-
drakon schrieb:
Dann wäre es in dem Sinne komplizierter, dass man teils vor einer "Auswahl" steht, wo man dann jedes mal in die Falle tritt und das falsche Keyword nimmt.

Naja, aber so ähnlich finde ich die beiden Dinge wirklich nicht, als dass Verwechslungsgefahr bestünde. Stell dir mal vor, niemand hätte den Vorschlag mit
= deletegebracht. Als Programmierer käme man niemals auf die Idee, eine Verbindung zwischen Speicherfreigabe und Methodenverbieten herzustellen! Wenn man von Anfang an ein separates Schlüsselwort hätte, würde man diese Dinge gar nie durcheinanderbringen. Aber so wird ein künstlicher Zusammenhang suggeriert.(z.B erinnerst du dich bestimmt an das Beispiel von letzens mit count/size. genau solche Sachen meine ich).
Ja, gut, das muss halt mal von der Sprache festgelegt werden. Ist ja innerhalb von C++ weitestgehend vereinheitlicht. Bei
std::stringkonnte man sich wohl nicht ganz entscheiden...