Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » vector<basisklasse> kopieren

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
12.10.2011, 16:17 Uhr
~yoko
Gast


Hallo zusammen,

ich habe mein Problem mal so weit runtergebrochen wie möglich. Bin ein Anfänger in C++ und kenne mich gerade im Bereich Vererbung und Polymorphismus sehr schlecht aus. Nach stundenlanger Suche verzweifle ich nun und erstelle meinen ersten Thread.

Ich würde gerne einen Vektor kopieren, der als Typ die Basisklasse enthält. Allerdings weiß ich nicht richtig wie. Möchte ich auf die kopierten Objekte der Child-Klasse zugreifen, so funktioniert das nicht.
Mein bisheriger Ansatz war nicht erfolgreich (siehe folgender Code)


C++:
#include <vector>

using namespace std;



class strassenobjekt
{
public:
int typ;
int abstand_links;
int abstand_rechts;

strassenobjekt(int typ,int abstand_links, int abstand_rechts)
{

this->typ = typ;
this->abstand_links = abstand_links;
this->abstand_rechts = abstand_rechts;
}
virtual int getValue()
{
return -1;
}
};



class lane : public strassenobjekt
{
public:
int laneStyle;

lane(int lanestyle, int typ, int abstand_links, int abstand_rechts)
: strassenobjekt(typ,abstand_links, abstand_rechts),laneStyle(lanestyle)
{

}

int getValue()
{
return laneStyle;
}
};



class barrier: public strassenobjekt
{
public:
int barrierStyle;

barrier(int barrierstyle, int typ,int abstand_links, int abstand_rechts)
: strassenobjekt(typ,abstand_links, abstand_rechts),barrierStyle(barrierstyle)
{

}

int getValue()
{
return barrierStyle;
}
};



int main()
{

vector<strassenobjekt*> * Liste1 = new vector<strassenobjekt*>;
vector<strassenobjekt*> * Liste2 = new vector<strassenobjekt*>;

lane * linie1 = new lane(1,2,3,4);
barrier * linie2 = new barrier(5,6,7,8);
Liste1->push_back(linie1);
Liste1->push_back(linie2);

*Liste2 = *Liste1; //damit die Größe auch stimmt
for(int i = 0; i<Liste1->size();i++)
{
strassenobjekt * das_i_te = new strassenobjekt(0,0,0); //Hier liegt wohl das Problem...
*das_i_te = *Liste2->at(i); //Wert von Adresse
Liste2->at(i)=das_i_te; //Adresse wird geändert, Wert bleibt gleich

}

strassenobjekt *test1 = Liste1->at(1);
strassenobjekt* test2 = Liste2->at(1);

cout << test1->getValue() << endl;
cout << test2->getValue() << endl;
cout
};



Output:

5
-1



Also das Problem bei der ganzen Geschichte ist, dass die Basisklasse-Attribute kopiert werden, aber nicht das Objekt an sich.. Somit habe ich nurnoch die Attribute der Basisklasse und das Objekt weiß nicht, dass es eigentlich von der Klasse "lane" sein soll.



Viele Grüße

yoko

Dieser Post wurde am 12.10.2011 um 18:36 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
12.10.2011, 18:38 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


naja eigentlich logisch, du kopierst hier

C++:
*das_i_te = *Liste2->at(i); //Wert von Adresse



nur deine Attribute deiner basisklasse "strassenobjekt" - was anderes kennt strassenobjekt (das_i_te) ja nicht.

Da gibts auch nen Fachausdruck für diese Art von "Problem" - fällt mir nur grad nicht ein ;-)
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
15.10.2011, 15:26 Uhr
0xdeadbeef
Gott
(Operator)


Au weia. Du leckst Speicher wie ein Küchensieb. C++ hat keinen Garbage-Collector, das ist dir hoffentlich klar.

Der Ausdruck, nach dem FloSoft sucht, ist "Slicing". Du weist dem Objekt hinter dem Zeiger das_i_te das Objekt hinter *Liste2->at(i) zu, und das kann halt die Extra-Attribute der Kindklasse nicht halten. Wenn ich richtig verstehe, was du da vorhast, suchst du nach virtuellen Konstruktoren.

Im Übrigen gibt es keinen Grund, Liste1 und Liste2 auf den Heap zu packen; nichts spricht gegen

C++:
vector<strassenobjekt*> Liste1, Liste2;


In der Tat ist das besser, weil sie sich dann selbst aufräumen können. Allerdings: Ihr Inhalt ist in diesem Fall ein Array von Zeigern, von denen sie nicht wissen können, ob sie vom Heap gelöscht werden müssen, also versuchen sie es erst gar nicht. Du musst dich selbst darum kümmern, dass der Speicher, auf den sie verweisen, wieder freigegeben wird. Zu jedem new gehört ein delete, zu jedem new[] ein delete[], und die kannst du nicht einfach so unterschlagen.

Man arbeitet in C++ gerade in unübersichtlichen Fällen, wie du sie hier zu haben scheinst, deswegen ungern mit nackten Zeigern. An deiner Stelle würde ich mir überlegen,

C++:
std::vector<std::tr1::shared_ptr<strassenobjekt> > Liste1, Liste2;


zu verwenden, um mich nicht mehr selbst kümmern zu müssen. std::tr1::shared_ptr ist ein sogenannter "smart pointer", der einen Referenzzähler unterhält. Wenn der letzte shared_ptr, der einen Zeigerwert hält, diesen verliert (weil er zerstört oder ihm ein anderer zugewiesen wird), wird das Objekt, auf das dieser zeigt, zerstört. Es ist in den meisten Fällen eine bequeme Variante, die ganze Problematik zu umgehen.

Ansonsten ist Boosts Pointer-Container-Bibliothek einen Blick wert.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (WinAPI, Konsole) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: