Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
-
hupfdule
- Beiträge: 1864
- Registriert: 09.12.2002 15:04:37
- Wohnort: Berlin
-
Kontaktdaten:
Beitrag
von hupfdule » 27.09.2004 08:31:19
Hi,
ich versuche mich gerade ein bisschen an C++ und wie zu erwarten stelle ich mich dabei ziemlich dämlich an. Ich habe folgendes Problem.
Eine abstrakte Klasse, von der zwei "richtige" Klassen abgeleitet sind. Eine dieser richtigen Klassen hat ein Feld vom Typ der abstrakten Klasse (da es dort sowohl ein Objekt seiner eigenen, als auch der zweiten Klasse drin speichern können soll). Folgender Quellcode kommt da also zusammen:
Code: Alles auswählen
class A{
int x;
int y;
public:
virtual int getX() {return x;}
virtual int getY() {return y;}
virtual int doSomething() = 0;
};
class B: public A{
};
class C: public A{
A parent;
};
int main(){
}
Nur leider funktioniert das nicht so wie ich mir das vorstelle, denn beim Übersetzen beschwert sich g++:
Code: Alles auswählen
test.cpp:15: cannot declare field `C::parent' to be of type `A'
test.cpp:15: since the following virtual functions are abstract:
test.cpp:7: int A::doSomething()
Nun wo habe ich hier den Denkfehler? Wie erreiche ich mein Vorhaben?
Gruß
Marco
-
Feytsch
- Beiträge: 33
- Registriert: 11.12.2003 09:54:10
Beitrag
von Feytsch » 27.09.2004 09:43:53
Hi!
Du musst nur in deinen Konkreten Klassen die Funktion doSomething implementieren, da sonst auch deine "Konkrete Klasse" abstrakt bleibt
PC: AMD Athlon 1.4-256 RAM -GForce 2 MX-Debian GNU/Linux (2.6.3) sarge
Notebook: Acer Aspire 2003WLMi - Debian GNU/Linux (2.6.7: ipw2001, fglrx) sarge
-
hupfdule
- Beiträge: 1864
- Registriert: 09.12.2002 15:04:37
- Wohnort: Berlin
-
Kontaktdaten:
Beitrag
von hupfdule » 27.09.2004 09:54:34
Das sollte doch aber eigentlich nicht nötig sein, da an dieser Stelle ja nicht fest steht welche Objekte dort landen sollen. Und dass dort abstrakte Objekte landen ist ja nicht möglich, da ich diese gar nicht instanzieren könnte.
Habs trotzdem mal ausprobiert, mit dem selben Ergebnis.
Jetziger Code:
Code: Alles auswählen
class A{
int x;
int y;
public:
virtual int getX() {return x;}
virtual int getY() {return y;}
virtual int doSomething() = 0;
};
class B: public A{
public:
virtual int doSomething(){
}
};
class C: public A{
A parent;
public:
virtual int doSomething(){
}
};
int main(){
}
Fehlermeldung ist weiterhin
Code: Alles auswählen
test.cpp:21: cannot declare field `C::parent' to be of type `A'
test.cpp:21: since the following virtual functions are abstract:
test.cpp:7: int A::doSomething()
-
Feytsch
- Beiträge: 33
- Registriert: 11.12.2003 09:54:10
Beitrag
von Feytsch » 27.09.2004 10:11:52
Hi nochmal!
Nimm in der Klasse B/C mal das schlüsselwort virtual weg, dann sollte es eigentlich funktionieren, da du dann erst wirkliche konkrete Klassen hast
PC: AMD Athlon 1.4-256 RAM -GForce 2 MX-Debian GNU/Linux (2.6.3) sarge
Notebook: Acer Aspire 2003WLMi - Debian GNU/Linux (2.6.7: ipw2001, fglrx) sarge
-
hupfdule
- Beiträge: 1864
- Registriert: 09.12.2002 15:04:37
- Wohnort: Berlin
-
Kontaktdaten:
Beitrag
von hupfdule » 27.09.2004 10:17:03
Hilft leider auch nicht.
So wie ich es verstanden hab, hat virtual aber auch keinen Einfluss darauf, ob eine Klasse abstrakt ist, sondern nur, ob die Methode überladen werden kann.
Noch weitere Ideen wo mein Fehler liegt?
-
peschmae
- Beiträge: 4844
- Registriert: 07.01.2003 12:50:33
- Lizenz eigener Beiträge: MIT Lizenz
- Wohnort: nirgendwo im irgendwo
Beitrag
von peschmae » 27.09.2004 10:19:56
Ich glaube da musst du Pointer verwenden damit das geht.
MfG Peschmä
"er hätte nicht in die usa ziehen dürfen - die versauen alles" -- Snoopy
-
Feytsch
- Beiträge: 33
- Registriert: 11.12.2003 09:54:10
Beitrag
von Feytsch » 27.09.2004 10:25:27
das hatte ich ganz überlesen .... peschmae hat recht, so sollte es gehn
PC: AMD Athlon 1.4-256 RAM -GForce 2 MX-Debian GNU/Linux (2.6.3) sarge
Notebook: Acer Aspire 2003WLMi - Debian GNU/Linux (2.6.7: ipw2001, fglrx) sarge
-
hupfdule
- Beiträge: 1864
- Registriert: 09.12.2002 15:04:37
- Wohnort: Berlin
-
Kontaktdaten:
Beitrag
von hupfdule » 27.09.2004 10:29:24
Danke, das ist es gewesen
Ein Frage dazu ohne es vorher probiert zu haben und ehrlich gesagt auch ohne die Konsequenzen dessen zu kennen. Geht das dann auch mit Referenzen oder nur mit Zeigern?
-
Joghurt
- Beiträge: 5244
- Registriert: 30.01.2003 15:27:31
- Wohnort: Hamburg
-
Kontaktdaten:
Beitrag
von Joghurt » 27.09.2004 12:55:30
hupfdule hat geschrieben:Geht das dann auch mit Referenzen oder nur mit Zeigern?
Mit Referenzen geht es auch, allerdings muss diese dann im Constructor definiert werden:
Code: Alles auswählen
struct A {
virtual int foo()=0;
};
struct B : public A {
A& aref;
B(A& classA);
};
B::B(A& classA) : aref(classA)
{
...
};
Den Constructor kannst du natürlich auch innerhalb der Klasse implementieren.
PS: Ich war schreibfaul und habe statt 'class' 'struct' geschrieben. Der einzige Unterschied ist, dass bei 'struct' automatisch "public" voreingestellt ist.
-
hupfdule
- Beiträge: 1864
- Registriert: 09.12.2002 15:04:37
- Wohnort: Berlin
-
Kontaktdaten:
Beitrag
von hupfdule » 27.09.2004 13:29:04
Danke, das hilft mir weiter. Aber was bedeuted denn folgendes Konstrukt?
Damit meine ich den Teil ab dem einzelnen Doppelpunkt. Das ist mir bisher noch nicht über den Weg gelaufen. Was genau sagt das aus?
-
Joghurt
- Beiträge: 5244
- Registriert: 30.01.2003 15:27:31
- Wohnort: Hamburg
-
Kontaktdaten:
Beitrag
von Joghurt » 27.09.2004 13:40:55
Der Doppelpunkt dient zum initialisieren: Z.B. kann man
Code: Alles auswählen
struct B { int a; int b;};
B::B()
{
a = 42;
b = 4711;
irgendwas anderes;
}
durch
ersetzen. Da du Referenzen nicht mit "=" zuweisen kannst, musst du die 2. Variante wählen; daüfr wurde sie IIRC auch eingeführt.
Allgemeint solltest du dir die 2. Schreibweise für alle Initialisierungen angewöhnen.
PS: Die ":"-Schreibweise gilt nur für Konstruktoren.
-
hupfdule
- Beiträge: 1864
- Registriert: 09.12.2002 15:04:37
- Wohnort: Berlin
-
Kontaktdaten:
Beitrag
von hupfdule » 27.09.2004 14:41:16
Danke, ich glaub ich habs verstanden