Objekte abgeleiteter Klassen in einem Vector
-
Hallo :-),
ich habe 3 Klassen: Pt, Sgt und Rct.
Sgt ist von Pt abgeleitet.
Rct ist von Sgt abgeleitet.Es gibt für alle drei Klassen unterschiedliche Print-Funktionen.
In der Header-Datei jeder Klasse ist außerdem der operator<< überschrieben, der die Print(ostream& s)-Funktion aufruft.Wenn ich jetzt Objekte aller drei Klassen erzeuge und sie über einen Zeiger ausgebe, klappt alles und die Print-Funktion der richtigen Klasse wird verwendet.
Packe ich diese Zeiger der Objekte jetzt in einen vector<Pt*> klappt das ganze nicht mehr - hier wird jetzt immer die Print-Funktion von der Basis-Klasse Pt aufgerufen.
Hier der Code:
main:#include "Rct.h" #include <iostream> #include <stdlib.h> #include <vector> using namespace std; int main() { Pt* a = new Pt(); Pt* b = new Pt(1,2); Pt* c = new Pt(7,8); Sgt* ab = new Sgt(*a,*b); Sgt* bc = new Sgt(*b,*c); Rct* r1 = new Rct(*b,*c); cout << *a << "\n" << *ab << "\n" << *bc << "\n" << *r1; // here the correct print()-function is called. vector<Pt*> objects; objects.push_back(a); // adding objects objects.push_back(ab); objects.push_back(r1); cout << "\nIterator-Test: \n"; for(std::vector<Pt*>::const_iterator i = objects.begin(); i != objects.end(); ++i) cout << **i << endl; // here it's not the correct function anymore. //*i->Print(); return 0; }
Pt.h:
#include <iostream> #ifndef PT_H_ #define PT_H_ using namespace std; class Pt { public: double x, y; Pt(); Pt(double X, double Y); virtual ~Pt(); virtual void Print(ostream& s) const; //{ s << "Pt(" << x << "," << y << ")"; } }; inline ostream& operator<<(ostream& s, Pt pt) { // Insert into a stream pt.Print(s); return s; } #endif /* PT_H_ */
Pt.cpp:
#include "Pt.h" Pt::Pt() : x(0), y(0) {} Pt::Pt(double X, double Y) : x(X), y(Y) {} Pt::~Pt() {} void Pt::Print(ostream& s) const {s << "Pt(" << x << "," << y << ")"; }
Sgt.h:
#include <iostream> #include "Pt.h" #ifndef SGT_H_ #define SGT_H_ class Sgt : public Pt { public: Pt p2; Sgt(); Sgt(Pt P1, Pt P2); virtual ~Sgt(); void Print(ostream& s) const; }; inline ostream& operator<<(ostream& s, Sgt sgt) { // Insert dans un flux sgt.Print(s); return s; } #endif /* SGT_H_ */
Sgt.cpp:
#include "Sgt.h" Sgt::Sgt() : p2(Pt(0,0)) {} Sgt::Sgt(Pt P1, Pt P2) : Pt(P1), p2(P2) {} Sgt::~Sgt() {} void Sgt::Print(ostream& s) const { s << "Sgt( "<<Pt(x,y) << ", " << p2 << " )"; }
Rct.h:
#include "Sgt.h" #ifndef RCT_H_ #define RCT_H_ class Rct : public Sgt { public: Rct(); Rct(Pt p1, Pt p2); virtual ~Rct(); void Print(ostream& s) const; }; inline ostream& operator<<(ostream& s, Rct rct) { // Insert dans un flux rct.Print(s); return s; } #endif /* RCT_H_ */
Rct.cpp:
#include "Rct.h" Rct::Rct() {} Rct::Rct(Pt p1, Pt p2) : Sgt(p1, p2) {} void Rct::Print(ostream& s) const { s << "Rct( "<<Pt(x,y) << ", " << p2 << " )"; } Rct::~Rct() {}
Vielen Dank schonmal im Voraus
-
...
-
lukas.braband schrieb:
inline ostream& operator<<(ostream& s, Rct rct) { // Insert dans un flux rct.Print(s); return s; }
Tss...die Franzosen...
Nimm eine Referenz oder einen Zeiger aufPt
, damit der Compiler die richtigePrint()
Funktion aufruft. Zeiger sind allerdings unüblich.Dein Beispiel revisited:
#include <iostream> #include <vector> #include <memory> struct Pt{ Pt(int x=0, int y=0) : x(x), y(y) {} virtual void print(std::ostream& out) const { out << "Pt(" << x << "," << y << ")"; } virtual ~Pt() {} private: int x,y; }; std::ostream& operator<<(std::ostream& out, const Pt& pt) { pt.print(out); return out; } struct Sgt : Pt{ Sgt(){} Sgt(const Pt& p1, const Pt& p2) : Pt(p1), p2(p2) {} void print(std::ostream& out) const { out << "Sgt(" << static_cast<Pt>(*this) << "," << p2 << ")"; } private: Pt p2; }; struct Rct : Sgt{ Rct() {} Rct(const Pt& p1, const Pt& p2) : Sgt(p1, p2) {} void print(std::ostream& out) const { out << "Rct(" << static_cast<Sgt>(*this) << ")"; } }; int main(){ std::vector<std::unique_ptr<Pt>> soldiers; soldiers.emplace_back(new Pt()); soldiers.emplace_back(new Pt(1,2)); soldiers.emplace_back(new Pt(7,8)); soldiers.emplace_back(new Sgt(*soldiers[0], *soldiers[1])); soldiers.emplace_back(new Sgt(*soldiers[1], *soldiers[2])); soldiers.emplace_back(new Rct(*soldiers[1], *soldiers[2])); for(const auto& it : soldiers) std::cout << *it << '\n'; }
Bonne chance!
-
Furble Wurble schrieb:
Tss...die Franzosen...
uups, da hab ich doch tatsächlich noch einen Franz-Kommentar vergessen^^.
Haha, ja, mache gerade 2 Auslands-Semester in Südfrankreich :). War immerhin positiv überrascht, dass alle Variablennamen englisch sind - gut wenn, die das aussprechen kann man sich schon wieder streiten, ob das englisch sein soll haha^^, aber gut, das ist ne andere Sache^^.Also gut - lange Rede, kurzer Sinn.
Vielen Dank für eure schnelle Hilfe !
Das Grobe habe ich soweit erstmal verstanden.
Ich verstehe allerdings noch nicht so ganz, wozu die static-casts in den Print-Funktionen jetzt gut sein sollen ?@ Swordfish:
Das ein Rct ein Sgt und ein Sgt ein Pt sein soll, hat sich mein Prof hier ausgedacht - ich hab mich auch gewundert :-/.Achso ja:
tausendmal :p :p
-
...