Vererbung
-
Hallo,
in Sachen Vererbung habe ich ein kleines Problem und würde mich über euere Hilfe freuen.Drei abstrakte Klassen sollen als Grundgerüst dienen.
// Namesgebung soll auf die Verwendung hinweisen class Haupt; class Nebenfunk1; class Nebenfunk2; // Abstraktes Gerüst class Haupt : public Nebenfunk1, public Nebenfunk2 { // .... }Für alle drei Klassen gibt es mehrere Implementierungen. Zudem soll jede von Haupt abgeleitete Klasse frei bei der Wahl der Nebenfunk-Implementierungen sein.
Ist folgendes richtig umgesetzt oder muss ich einen anderen Weg einschlagen?
// Namesgebung soll auf die Verwendung hinweisen class Haupt; class NewHaupt; class Nebenfunk1; class A1; class B1; class Nebenfunk2; class A2; class B2; // Abstraktes Gerüst template<class N1 = Nebenfunk1, class N2 = Nebenfunk2> // template erforderlich, da N1 und N2 fix sind? class Haupt : public N1, public N2 { // .... } class A1 : public Nebenfunk1 { // } class B1 : public Nebenfunk1 { // } class A2 : public Nebenfunk2 { // } class B2 : public Nebenfunk2 { // } template<class N1 = A1, class N2 = A2> class NewHaupt : public N1, public N2 { // }Ist das so richtig, oder hab ich den ein oder anderen Denkfehler?
Gruß,
Thomas
-
Ich sehe nicht warum Templates hier unbedingt notwendig sind, insbesondere wenn du eh schon template class Main hast, warum dann im selben Stil nochmal template class NewMain her muss.
Ist denn NewMain was komplett anderes als Main?Im übrigen hast du noch nen Fehler im Code:
Für Vererbung muss die komplette Basisklasse bekannt sein, nicht nur der Name.Vllt. beschreibst du erst mal was du erreichen willst, dann stellst du eine konkrete Frage, dann kann man dir auch wirklich helfen.
-
Servus,
wenn ich dich richtig verstehe, funzt folgendes
// Namesgebung soll auf die Verwendung hinweisen class Haupt; class NewHaupt; class Nebenfunk1; class A1; class B1; class Nebenfunk2; class A2; class B2; class Nebenfunk1 { public: void func1(); } class Nebenfunk2 { public: int func2(); } // Abstraktes Gerüst class Haupt : public Nebenfunk1, public Nebenfunk2 { public: bool funcHaupt(); } class A1 : public Nebenfunk1 { // ... } class B1 : public Nebenfunk1 { // ... } class A2 : public Nebenfunk2 {soll das Grundgerüst darstellen, dass // ... } class B2 : public Nebenfunk2 { // ... } template<class N1 = A1, class N2 = A2> class NewHaupt : public N1, public N2 { // ... }Vllt. beschreibst du erst mal was du erreichen willst, dann stellst du eine konkrete Frage, dann kann man dir auch wirklich helfen.
Ich möchte eine abstrakte Klasse nicht überladen und diese in Ihre logischen Bestandteile zerlegen und mittels Vererbung zusammen zu führen. Dies soll zu einer höheren Flexibilität führen.
Die Klasse Haupt dient als Grundgerüst. Mit einer Variablen "Haupt h" soll der Zugriff auf jede Standard-Aktion möglich sein.
Nebenfunk 1 und 2 sind abstrakt, daher müssen diese in der NewHaupt spezifiziert werden. Dies soll nicht direkt in der NewHaupt geschehen, sondern durch eine direkte Ableitung der Klassen und in NewHaupt zusammengeführt werden.Was mich interessiert
- Weiß der Compiler an dieser Stelletemplate<class N1 = A1, class N2 = A2> class NewHaupt : public N1, public N2 {, dass N1 und N2 die abstrakten Mehtoden aus Haupt implementieren?
class Haupt : public Nebenfunk1, public Nebenfunk2
-
ThomasEnzinger schrieb:
Servus,
wenn ich dich richtig verstehe, funzt folgendes
//code
Hmm sollte ja.
Bur dass du, wenn du die Klasse eh schon gleich definierst du dir das forward deklarieren schenken kannst.Ich möchte eine abstrakte Klasse nicht überladen und diese in Ihre logischen Bestandteile zerlegen und mittels Vererbung zusammen zu führen. Dies soll zu einer höheren Flexibilität führen.
Dies führt sicher nicht zu höherer Flexibilität, sondern eher zu ziemlichem Chaos

Kann es sein dass du aus C kommst? Eine Klasse ist ein in sich geschlossenes Konstrukt, welches mit den Membern und Methoden ein konkretes "Ding" beschreibt.
Um dir das zu erklären was du gerade versuchst ein kleines Beispiel:
Eine Mensch ist ein konkretes Objekt. Menschen und Industrieroboter haben etwas gemeinsam: Sie können greifen und haben dazu einen Arm. Gut, dann definieren wir eine Klasse Arm mit einer Methode greifen.
Was du jetzt machst ist folgendes:class Arm { public: void greifen(); }; class Mensch : public Arm { /// };Siehst du das Problem?
Vererbung ist ausdrückbar mit Ist-Ein. Ein Mensch ist aber definitiv KEIN Arm!
Also nicht versuchen eine Klasse zu zerstückeln, und dann per public-Vererbung wieder zusammenzusetzen.Was mich interessiert
- Weiß der Compiler an dieser Stelletemplate<class N1 = A1, class N2 = A2> class NewHaupt : public N1, public N2 {, dass N1 und N2 die abstrakten Mehtoden aus Haupt implementieren?
class Haupt : public Nebenfunk1, public Nebenfunk2Ähm, N1 und N2 implementieren nicht die abstrakten Methoden von Haupt!
A1 und A2 haben rein gar nix mit Haupt zu tun, nur dass A1 von Nebenfunk1, A2 von Nebenfunk2 und Haupt von Nebenfunk1 und Nebenfunk2 erben. Es sind vollkommen verschiedene Typen!Was ist denn der Hintergrund dass du dich zu so einem "Gemetzel" (=Zerstückeln von Klassen) genötigt siehst :D? Beschreib dein PROBLEM und nicht wie du es lösen willst.
-
Servus,
ähmm, ja. Da stand ich gestern etwas auf dem Schlauch. Vier Weißbier sind nicht immer gut

template<class N1 = Nebenfunk1, class N2 = Nebenfunk2> class Haupt : public N1, public N2Das wollte ich. Damit müsste ich folgendes machen können
class NewHaupt1 : public Haupt<B1, A2> { // .... } class NewHaupt2: public Haupt<A1> { // abstrakte Methoden von Haupt wird in NewHaupt2 implementiert } //...Und das sollte auch gehen
Haupt* h = new NewHaupt2(); h->wasweißich();
-
Kannst du bitte dein PROBLEM in Worten beschreiben, und nicht Code posten, was du codetechnisch erreichen willst!
Denn warum du ein template brauchst versteh ich nicht ganz.
Zur Info: Die Template-Parameter bestimmen den Type deiner Instanz. Wenn du vorhast, durch die Templates einfach einem Objekt Spezialisierungen von Nebenfunk1 unterzujubeln - das geht nicht!class A {}; class B : public A {}; template< typename N > class Haupt {}; int main() { Haupt<A> a; Haupt<B> b; a = b; // hier kracht es, denn ein B erbt zwar von A, ist aber für den Compiler was anderes! }Das einzige, wie du das Problem lösen könntest (mit templates), wenn du in Haupt für jeden erdenklichen Fall einen operator=/copyCTor anbietest, in diesem Fall hieße der so:
Haupt<N>& operator=(const Haupt<B>& other);Einzige Option, wenn du das erreichen willst: Runtime-Polymorphie + Aggregation.