Anfängerfrage zum instanzieren von abgeleiteten Klassenobjekten
-
Hallo,
ich habe eine Basisklasse "Control", von der ich gerne diverse weitere Controls ableiten möchte.
Dazu übergebe ich im Konstruktor meiner Basisklasse 2 Parameter, einmal eine Referenz auf GuiRenderer und einmal auf das Parent-Control:
Control::Control(GuiRenderer *guiRenderer, Control *parent) : m_width(100), m_height(25), m_top(0), m_left(0), m_isDirty(true) { m_pGuiRenderer = guiRenderer; m_pParent = parent; }
Jetzt würde ich gerne eine Klasse "MainWindow" von "Control" ableiten.
Doch egal was ich bislang versuche, bekomme ich die Situation das der Compiler
meckert das ich mich nicht an den Standard-Construktor von Control halten
würde:#pragma once #include "Control.h" class MainWindow : Control { public: // Destruktor ~MainWindow(void); };
// MainWindow erzeugen MainWindow *mainWindow = new MainWindow(pGuiRenderer, NULL);
In C# wäre dies kein Problem, da ja MainWindow von Control ableitet. In C++ jedoch sagt mir der Compiler jedoch folgendes:
2 IntelliSense: Keine Instanz des Konstruktors ""MainWindow::MainWindow"" stimmt mit der Argumentliste überein.
Argumenttypen sind: (GuiRenderer *, int) d:\MyProject\Main.cpp 33 43 MyProject
Fehler 1 error C2660: 'MainWindow::MainWindow': Funktion akzeptiert keine 2 Argumente d:\MyProject\main.cpp 33 1 MyProjectAber warum?
-
Wenn Du von Deiner abgeleiteten Klasse eine Instanz bilden willst, muss zuerst der Konstruktor der Basisklasse(n) aufgerufen werden, dann erst wird der Konstruktor der abgeleiteten Klasse aufgerufen.
Wenn die Basisklasse aber keinen Default-Konstruktor, der ohne Argumente aufgerufen werden kann, hat, muss der Konstruktor der abgeleiteten Klasse den (einen) Konstruktor der Basisklasse aufrufen, in Deinem Fall etwa so:#include "Control.h" class MainWindow : Control { public: MainWindow(GuiRenderer *grptr, Control *cptr) : Control(grptr, cptr){} // Destruktor ~MainWindow(void); };
denn sonst kann der Teil Deiner Klasse, der Basisklasse ist, nicht konstruiert werden.
-
Du musst schon noch einen passenden Konstruktor für MainWindow schreiben (der dann den Control-Konstruktor in seiner Initialisierungsliste aufruft). Analogie: wenn du einen Hund erzeugen möchtest, geht das nicht, indem du ein Haustier erzeugst.
Wenn dein Compiler alle C++11-Features beherrscht, kannst du übrigens auch Konstruktoren erben. Jedoch ist mir keine Implementierung bekannt, die derzeit die geerbten Konstruktoren beherrscht und aufgrund des geringen Bedarfs wird sich das wohl auch nicht so schnell ändern, wenn überhaupt jemals.Ohne den ganzen Code zu kennen: Mein Instinkt sagt mir, dass du weder den Destruktor, noch die ganzen Pointer, noch das new haben möchtest und dass das allesamt Designfehler sind.
-
Vielen herzlichen dank für eure Antworten.
@SeppJ: dass kann möglich sein, ich merke leider immer mehr wie sich C# und C++ dahingehend unterscheiden. Programmiere jetzt einige Jahre lang in C# und komme mir bei C++ vor wie ein absoluter Programmieranfänger. Hätte anfangs nicht gedacht das es da so gravierende Unterschiede gibt (oder ich empfinde dies so).
-
Matze1974 schrieb:
In C# wäre dies kein Problem, da ja MainWindow von Control ableitet.
In C# werden Konstruktoren genau so wenig vererbt wie in C++.
Du hättest in C# also genau das selbe Problem.
Lediglich die Syntax zum Aufrufen des Basisklassen-Konstruktors ist anders (C++: BasisKlassenName(...)
, C#: base(...)
).
-
Aber unter .NET (C#/VB.NET) kann ich ja im Ctor "MyClass" und "MyBase" verwenden, was es ja unter nativem C++ nicht gibt (oder?). Das ist schon ein gravierender Unterschied, finde ich.
Oder zumindest ein Verständnisproblem -> welches ich hier gerade hab
-
Matze1974 schrieb:
Aber unter .NET (C#/VB.NET) kann ich ja im Ctor "MyClass" und "MyBase" verwenden, was es ja unter nativem C++ nicht gibt (oder?).
Unwahrscheinlich. Wobei unklar ist, was du meinst. Zeig mal ein Codebeispiel (eines, das auch funktioniert).
-
Okay, bereite ich vor (heute jedoch nicht mehr), ich werde es morgen abend posten.
-
Matze1974 schrieb:
Aber unter .NET (C#/VB.NET) kann ich ja im Ctor "MyClass" und "MyBase" verwenden, was es ja unter nativem C++ nicht gibt (oder?). Das ist schon ein gravierender Unterschied, finde ich.
Oder zumindest ein Verständnisproblem -> welches ich hier gerade habDer grundlegende Unterschied ist, dass C++ Mehrfachvererbung unterstützt und .NET Sprachen das nicht tun.
Daher reicht bei .NET Sprachen ein einfaches "base" oder "MyBase" oder was auch immer -- man kann ein fixes Keyword nehmen das für "die Basisklasse" steht, weil es nicht mehr als eine Basisklasse geben kann.
Und in C++ halt nicht, weil da durchaus mehr als eine Basisklasse geben kann. Deswegen musst du in C++ statt "base" oder "MyBase" den Namen der Basisklasse schreiben.