C++ Abstrakte Klasse als Basisklasse

Die Fi

Lt. Junior Grade
Registriert
Aug. 2005
Beiträge
298
Hi, ich hab zur Zeit ein kleines Problem welches ich als Anfänger nicht ganz in den Griff bekomme. Ich habe 4 Klassen
  1. Eine für sich alleine stehende Klasse A
  2. Eine Basis Klasse B (soll abstrakt sein
  3. 2 abgeleitete Klassen C, D von Basisklasse B

Meine frage ist, wenn ich nun in der Basis Klasse pirvate Variablen definiere, die ich dann an die abgeleiteten Klassen vererben möchte aber es so hinschreibe

Code:
class C: public B
werden die privaten Variablen mit übernommen oder nicht?

Bsp.:
Code:
class B
  privte:
    int a;
    double b;
  
  public:
  //Methoden um auf a und b zuzugreifen
  virtual void v_methode();

class C : public B
  private:
    float c;
  
  public:
    //Methoden
    void v_methode

Die Frage besitzen jetzt die Objekte von C auch die Variablen a, b die in dem privat Bereich der Basisklasse B deklariert wurden?
 
Zuletzt bearbeitet:
ja, das objekt vom typ klasse c besitzt auch die privaten variablen aus der basis klasse b.
ABER: eine funktion, die in C definiert wurde (nicht mit deklariert verwechseln) kann nicht auf diese variablen zugreifen. das geht nur auf protected oder public variablen.

aber geerbte methoden aus b können weiterhin auf die privaten geerbten variablen zugreifen.
 
probiers doch einfach aus? kannst ja ma ne Instanz von C erstellen und probieren auf ne private membervariable zuzugreifen, die zu B gehört.

Ein Tipp ist noch Membervariablen (a, b) einen besonderen Namen zu geben.
Bei uns an der Uni war es üblich "_" vor die Variablennamen zu setzen, wenn es sich um membervariblen (Attribute) handelt. Also _a.
So spart man sich später Probleme beim Code-lesen und ständige "this" verwendung.
N anderer üblicher Name ist m_a für "membervariable a"
 
Ok gut, das wäre geklärt.
Dann verstehe ich aber nicht wieso mein Visual Studio beim Kompilieren meckert, das die Basis Klasse B nicht deklariert wurde... (ja, #include "B.h" ist in der C.h und in der C.cpp, dafür ist die B.h in #ifndef _B_H_ für den Compiler definiert um mehrfach inkludieren zu verhindern)

Wichtig ist wahrscheinlich noch zu wissen, dass in der Basis Klasse B ein Bezug auf die Klasse A gibt

quasi

Code:
class B
  privte:
    int a;
    double b;
    A *aObj;
  
  public:
  //Methoden um auf a und b zuzugreifen
  virtual void v_methode();

Ich frage mich nämlich, ob ich irgendwie einen Fehler mit der Vorwärtsdeklaration bekomme. Wenn ich nun dieses *aObj im private Bereich von B definiere.

@kuddlemuddle das mit den Variabelnamen ist schon klar, ich wollte es erst mal einfach gestalten ^^.

2. Wie sieht es aber mit dem Konstruktor von der abgeleiteten Klasse? Abstrakte Klassen, haben ja keinen Konstruktor, da sie ja nicht im Stande sind Objekte zu erzeugen.
 
Zuletzt bearbeitet:
erstmal ist das private falsch geschrieben.

zweitens sagtest du nicht, du wolltest ne abstrakte klasse b? dann musst du die eine methode auf null setzen, sonst musst du sie uch definieren, was aber die klasse dann nicht mehr abstrakt macht.

d.h.:

virtual void v_methode() = 0;


damit wird die methode abstract gehalten. ein klasse die b erbt muss dann natürlich diese methode definieren, da man keine instanz bilden kann, wenn abstrakte methoden vorhanden sind.

wegen der fehlermeldung, offenbar gab es schon fehler bei deiner klasse B, weswegen sie nie deklariert wurde und damit für die deklaration der klasse c nicht zur verfügung stand.

poste mal den kopletten compilier log.
 
Man spricht bei funktionen wie virtual void func() = 0; von rein virtuellen Funktionen. Siehe auch: http://de.wikipedia.org/wiki/Virtuelle_Methode#Rein-virtuelle_Methoden

2. Wie sieht es aber mit dem Konstruktor von der abgeleiteten Klasse? Abstrakte Klassen, haben ja keinen Konstruktor, da sie ja nicht im Stande sind Objekte zu erzeugen.
Du kannst mit dem Konstruktor deiner Klasse auch Elemente der Basisklasse intialisieren.

Aber bevor wir hier weiter raten: Kompletter Code und Compilerausgabe!

Gruß,

badday
 
Hier ist das ganze Programm und die sln für Visual Studio 2008.

Beim kompilieren, werdet ihr merken das sich das ganze Problem um:
Code:
error C2504: 'Basis': Basisklasse undefiniert	*\roboter.h 18
was höchstwahrscheinlich durch das verursacht wird:
Code:
error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.	*\basis.h	24
 
Zuletzt bearbeitet:
Mal fix ohne Compiler geschaut - du inkludierst zirkulär.

Wirf aus Basis.h das #include "Wippe.h" raus und mach dafür eine Forwarddeklaration
Code:
class Wippe;
rein.

Falls dann noch Fehler kommen - bitte nochmal die Fehlermeldungen (inklusive, bei welcher .cpp-Datei der Fehler beim Übersetzen aufgetreten ist) und den Source hochladen.
 
Zuletzt bearbeitet:
ok danke H4c3r ich hab mit der include genau das erreicht, was ich verhindern wollte ^^. (Wer lesen kann ich klar im Vorteil)

Die Folgenden Probleme drehen sich um die Konstruktoren für die abgeleiteten Klassen.
Fehler ist folgender:
Code:
error C2512: 'Basis': Kein geeigneter Standardkonstruktor verfügbar *\roboter.cpp	(9)
und die daraus folgenden Probleme beim deklarieren der Folgevariablen, die aus Basis abgeleitet wurden. a, m, v, vorzeichen etc.

Das selbe Spiel bei der 2ten abgl. Klasse
Code:
error C2512: 'Basis': Kein geeigneter Standardkonstruktor verfügbar *\spieler.cpp	(13)


PS: die Zahlen in den Klammern sind die Zeilen. Die ganzen Fehler, kannst du übrigens aus dem "..\Debug\BuildLog.html" entnehmen.
 

Anhänge

Immernoch keinen Compiler zur Hand ^^ Aber wenn ich es richtig sehe, hast du immernoch das zirkuläre include-Problem. Kick mal #include "Wippe.h" aus Roboter.h . Das include wird dort auch garnicht benötigt (man sollte sowieso immer nur exakt das inkludieren, was in dem Header tatsächlich benötigt wird und nicht über forward-Deklarationen gelöst werden kann). Mit Spieler sollte das Problem dann ähnlich gelagert sein, denke ich.
 
Dieses Wippe.h benötige ich glaub ich weil ich dann in der Methode simulationsSchritt() mit den Methoden der Wippe arbeiten muss.

Wie gesagt wenn du alle Fehlermeldungen sehen möchtest musst du nur die Zip runterladen und unter Debug nach BuildLog.html suchen. Da werden alle Fehlermeldungen mit Quelle angegeben.
 
Zuletzt bearbeitet:
Ganz ehrlich ich versteh nicht, wo ich sonst zirkulär inkludiere. Wen ich z.B aus Roboter die #include Wippe.h entferne, bekomme ich später in der spieler.cpp das problem das der "wippe-> " Zeiger nicht erkannt wird.
  • Code:
    error C2227: Links von "->getPhi" muss sich ein Zeiger auf Klassen-/Struktur-/Union-/generischen Typ befinden.	*\spieler.cpp (27)
    Für mich sieht es so aus, als ob er nicht erkennt, das in der bereits in der Basisklasse wippe als Zeiger von Wippe deklariert wurde. (Wippe *wippe;)
  • Die Frage ist: Wird dieser Fehler durchs zirkuläre Inkludieren verursacht?
    Code:
    error C2512: 'Basis': Kein geeigneter Standardkonstruktor verfügbar *\roboter.cpp	(9)
    Wenn ja bräuchte ich eine Erklärung wie genau.
  • z.B. ist mir nicht ganz klar, wie es mit der Spieler.cpp aussieht, welche nun mit dem Wippenzeiger arbeitet.
    Wenn ich nun class Wippe in Basis.h vor deklariert habe und nun in der abgeleiteten class Spielerdamit arbeitet möchte, muss ich die class Wippe wieder vordeklarieren, oder weiss der Compiler, das es bereits in den Basis.h gemacht wurde?

    Edit: Ich bin auch dem Vorschlag nachgekommen, und habe alle Header includes aus dem Class Header entfernt (ausser Basis.h in den abgeleiteten Klassen) und in die .cpps angehängt, trotzdem tritt der der C2512 Fehler auf.
 
Zuletzt bearbeitet:
Zurück
Oben