Spezialisierung
-
Hallo, ich habe eine Basis-Klasse Atom und eine Klasse Molekül.
Molekül enthält einen Vektor an Atomen.Nun möchte ich spezielle Moleküle schaffen, welche nur bestimmte Atome aufnehmen können und weiß nicht wie oder ob das geht.
class Atom {}; class Molecule { vector<Atom*> atoms; }; class SpecialAtom {}; class SpecialMolecule { vector<SpecialAtom*> atoms; };Das kompiliert zwar so (wenn ich eine main anlege), aber ich habe die Vermutung dass ich Zwei Vektoren anlege (vom Typ Atom und SpecialAtom). Ich bin mir da aber nicht ganz sicher, da meine C++ Kenntnisse eher gehobenem Anfängerniveau entsprechen.
Wie man das am besten löst weiß ich jetzt leider nicht.
(Mir flattern zwar Begriffe wie Templates oder virtuelle Verebung durch den Kopf, aber irgendwie scheint das alles nicht ganz zuzutreffen).
-
Da ich endlich wieder einen Rechner unter den Fingern habe, habe ich mal ein wenig probiert:
/* * main.cpp * * Created on: 03.04.2012 * Author: anubis */ #include <iostream> using namespace std; class Base { public: int a; Base(): a(4) {} }; class Derived : public Base { public: string a; Derived(): a("Hallo Welt") {} }; void info(Base* b) { cout << b-> a << endl; } int main() { Base* b = new Derived; Derived d; cout << b->a << endl; cout << d.a << endl; info(b); return 0; }Die Ausgabe, die mich ehrlich gesagt verwundert:
4
Hallo Welt
4Wieso gibt b->a die 4 zurück und nicht "Hallo Welt" . Ich hätte eine Überdeckung vermutet.
Besitzt b überhaupt das String-Attribut?
-
Gib doch erstmal den Membervariablen der einezelnen Klassen eindeutige Namen. Was soll denn a für "Derivad" sein; int a; oder string a?
Gruß
-
Wieso gibt b->a die 4 zurück und nicht "Hallo Welt" . Ich hätte eine Überdeckung vermutet.
b ist ein Pointer auf Base. Wenn du also b->a schreibst, denkt der Compiler sich, dass du den a-Member von Base meinst, also 4.
Das Objekt, auf das b zeigt, hat aber sowohl int als auch string als Member:class Base { public: int a; Base(): a(4) {} virtual void info() {cout << a << '\n';} }; class Derived : public Base { public: string a; Derived(): a("Hallo Welt") {} void info() {cout << Base::a << ' ' << a << '\n';} }; void info(Base* b) { cout << b-> a << endl; } int main() { Base* b = new Derived; Derived d; cout << b->a << endl; cout << d.a << endl; b->info(); d.info(); return 0; }4 Hallo Welt 4 Hallo Welt 4 Hallo Welt
-
Da gibt es keine Überdeckung. Lediglich wenn du aus Derived auf a zugreifen willst, wird es wohl etwas komplizierter (this->Base::a oder ähnliches). Da der Compiler nur einen Base-Zeiger sieht, greift er auch auf das a von Base zu. Ein Verhalten wie du es willst kannst du durch virtuelle Funktionen erreichen.
EDIT: Zu langsam...
