FB18 - Das Forum für Informatik

fb18.de / Off-Topic / Hard- und Softwarefragen

c++ Vector aus Pointern

c++ Vector aus Pointern 2009-02-19 00:01
Anonymer User
Hallo.
Ich habe ein Problem bei folgendem Schema:
Programmiert werden soll eine Verkettete Liste:

Zur Zeit folgendermaßen

class Knoten { private: std::string _name; //Knoten std::string _value; //Wert Knoten *_child; //Nachfolger ... }
Nach dieser Implementierung kann ein Knoten aber nur einen einzigen Nachfolger haben. wie bekomm mehrere Nachfolger je Knoten hin?

mein trick:
std::vector<Knoten> *_child; //Nachfolgergeht leider nicht :(
Ne andre Idee jmd?

Damit zusammenhängend die Frage nach dem Destructor.
Gibts ne elegante Möglichkeit beim Löschen eines Knotens alle nachfolgenden Kinder dieses Knotens zu löschen?

RE: c++ Vector aus Pointern 2009-02-19 00:03
Fred
Nach dieser Implementierung kann ein Knoten aber nur einen einzigen Nachfolger haben. wie bekomm mehrere Nachfolger je Knoten hin?
std::vector<Knoten*> _children; //Nachfolger
Aber warum willst Du mehrere Nachfolger haben? Bei einer verketteten Liste hat jeder Knoten nur einen Nachfolger. Willst Du das auf n-äre Bäume generalisieren?

RE: c++ Vector aus Pointern 2009-02-19 00:07
Anonymer User
ähm..ja…und wie kann ich dann auf die member des Vectors zugreifen?

RE: c++ Vector aus Pointern 2009-02-19 00:10
Fred
ähm..ja…
Ein Knoten mit mehreren Nachfolgern hat nichts mit einer verketteten Liste zu tun. Schau Dir mal diese Liste an:

h -> a -> l -> l -> o

Hier hat jeder Knoten nur einen Nachfolger, trotzdem kann man ohne Probleme eine Liste mit 5 Elementen bauen.

und wie kann ich dann auf die member des Vectors zugreifen?
http://www.cplusplus.com/reference/stl/vector/

RE: c++ Vector aus Pointern 2009-02-19 00:10
Anonymer User
ich will nen baum aufbauen, und da hat nen knoten halt ab und an mehrere Kinder….

RE: c++ Vector aus Pointern 2009-02-19 00:12
Fred
Gibts ne elegante Möglichkeit beim Löschen eines Knotens alle nachfolgenden Kinder dieses Knotens zu löschen?
Einfach im Desktruktor des Knotens den Nachfolgeknoten löschen.
~Knoten() { delete _child; _child = 0; // Vorsicht ist besser als Nachsicht [25] } Das setzt natürlich voraus, dass alle Knoten auf dem Heap erzeugt wurden.

RE: c++ Vector aus Pointern 2009-02-19 00:12
Anonymer User
und wie kann ich dann auf die member des Vectors zugreifen?
http://www.cplusplus.com/reference/stl/vector/

_children.MEMBER() geht nicht!!!

RE: c++ Vector aus Pointern 2009-02-19 00:15
Fred
Programmiert werden soll eine Verkettete Liste
ich will nen baum aufbauen, und da hat nen knoten halt ab und an mehrere Kinder….
So schnell kann sich eine Spezifikation ändern [22]
_children.MEMBER() geht nicht!!!
Ganz ehrlich, was erwartest Du denn, was da rauskommen sollte? Warum sollte es eine .MEMBER() Funktion geben?

Du kannst mittels .push_back(x) Knoten zum Vector hinzufügen, den Vector mittels .size() nach seiner Größe fragen und ihn wie ein Array indizieren.

Hier ein einfaches Anwendungsbeispiel eines Vektors von Zahlen:
std::vector<int> zahlen; zahlen.push_back(11); zahlen.push_back(13); zahlen.push_back(17); zahlen.push_back(19); for (int i = 0; i < zahlen.size(); ++i) {     std::cout << zahlen[i] << std::endl; } Das musst Du jetzt bloss auf Knoten* übertragen.

RE: c++ Vector aus Pointern 2009-02-19 00:22
Anonymer User
_children.MEMBER() geht nicht!!!
Ganz ehrlich, was erwartest Du denn, was da rauskommen sollte? Warum sollte es eine .MEMBER() Funktion geben?

Whooohoooo… Mooooooment.
Fred, du missverstehst mich.
Also

in der header Datei steht nu unter andrem:

class Knoten {
private:
std::string _name; //Knoten
std::string _value; //Wert
std::vector<Knoten*> _children; //Nachfolger
}

in der c++ Datei
versuche ich jetzt zb. im Konstructor auf den Vector zuzugreifen:
allerdings ist laut IntelliSense der Vector _children gar nicht vorhanden. Demnach kann ich auch mittels . nicht auf Member zugreifen. (MEMBER() war ein synonym für memberFx XY..)

#include <vector> is übrigens drinne…

Zum Destruktor. Jo. So hatte ich den auch schon. Allerdings hab ich bei mehreren Nachfolgern halt das problem, dass ich alle Elemnte des VEctors abklappern muss…Hab das zur Zeit mitm Iterator gemacht. Frage is halt nur obs einfacher geht ;)

RE: c++ Vector aus Pointern 2009-02-19 00:32
Fred
allerdings ist laut IntelliSense der Vector _children gar nicht vorhanden.
Ach so. Mit Intellisense kenne ich mich nicht aus. Projekt komplett neu kompilieren oder sowas, vielleicht hilft das ja?
Ansonsten halt blind programmieren, ich kenn das gar nicht anders in C++ [28]

Hab das zur Zeit mitm Iterator gemacht. Frage is halt nur obs einfacher geht ;)
Sicher, in C++ geht alles [25]
#include <algorithm> #include <vector> class Knoten {     // ...     std::vector<Knoten*> _children;     static void loeschen(Knoten* knoten)     {         delete knoten;     } public:     // ...     ~Knoten()     {         std::for_each(_children.begin(), _children.end(), loeschen);         _children.clear(); // Vorsicht ist besser als Nachsicht     } };

RE: c++ Vector aus Pointern 2009-02-19 00:39
Anonymer User
allerdings ist laut IntelliSense der Vector _children gar nicht vorhanden.
Ach so. Mit Intellisense kenne ich mich nicht aus. Projekt komplett neu kompilieren oder sowas, vielleicht hilft das ja?
Ansonsten halt blind programmieren, ich kenn das gar nicht anders in C++ [28]

Sorry, da is eben alles durcheinander geraten..
Das wird nicht gehen, das einfach alles per hand zu coden. Hab das projekt komplett "bereinigen" lassen. Aber leider gehts nich: :(
error C2065: 'children': nichtdeklarierter Bezeichnermeint er immer

RE: c++ Vector aus Pointern 2009-02-19 00:40
Fred
children
_children

Hmmm…

RE: c++ Vector aus Pointern 2009-02-19 00:41
Anonymer User
children
_children

Hmmm…

jo…Fehlermeldung einfach falsch kopiert, sorry. sollte beides mal _children sein….
Fehler also immernoch da :(

RE: c++ Vector aus Pointern 2009-02-19 00:47
Fred
Poste mal .h und .cpp komplett, sonst kommen wir wohl nicht weiter.

Aber probier doch ruhig einfach mal folgende Zeile zu schreiben:
_children.size();Geht das oder nicht?

RE: c++ Vector aus Pointern 2009-02-19 00:52
Anonymer User
ich habe den Ordner mit dem Projekt jetzt mal komplett (incl. debugfiles usw…) kopiert. Die Kopie mittels VS 9 gestartet. Jetzt findet er den Vector auch IntelliSense geht….

Im OriginalOrdner gehts immernoch nich..


Jetzt kommst du, denn mir macht MicroSoft ANGST!

RE: c++ Vector aus Pointern 2009-02-19 00:54
Fred
Die Kopie mittels VS 9 gestartet.
Womit arbeitest Du denn sonst?

RE: c++ Vector aus Pointern 2009-02-19 00:57
Anonymer User
Die Kopie mittels VS 9 gestartet.
Womit arbeitest Du denn sonst?

auch VS 9. Nicht verwirren lassen, denn ich bins augenscheinlich schon komplett.
Es ist alles gleich (auch die Programme!). Bis auf den Ordnernamen!!!

RE: c++ Vector aus Pointern 2009-02-28 00:21
Anonymer User
Sicher, in C++ geht alles [25]
#include <algorithm> #include <vector> class Knoten {     // ...     std::vector<Knoten*> _children;     static void loeschen(Knoten* knoten)     {         delete knoten;     } public:     // ...     ~Knoten()     {         std::for_each(_children.begin(), _children.end(), loeschen);         _children.clear(); // Vorsicht ist besser als Nachsicht     } };

Äh..:Fred, ich brauch noch mal Hilfe:

Ausgabe:
1>Kompilieren…
1>Knoten.cpp
1>Verknüpfen…
1>Knoten.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: static void __cdecl Knoten::loeschen(class Knoten *)" (?loeschen@Knoten@@SAXPAV1@@Z)" in Funktion ""public: virtual __thiscall Knoten::~Knoten(void)" (??1Knoten@@UAE@XZ)".
1>D:\Test\Debug\einfach_verkettete_LISTE.exe : fatal error LNK1120: 1 nicht aufgelöste externe Verweise.

:(

RE: c++ Vector aus Pointern 2009-02-28 11:19
Fred
Also bei mir klappt's einwandfrei. Das hat wahrscheinlich mit der Trennung in Header-Dateien und Implementations-Dateien zu tun, welche ich selten praktiziere.

Probier doch mal folgendes:

knoten.h
class Knoten {     // ...     std::vector<Knoten*> _children;     static void loeschen(Knoten* knoten); public:     // ...     ~Knoten(); };
knoten.cpp
#include <algorithm> #include <vector> #include "knoten.h" void Knoten::loeschen(Knoten* knoten) {     delete knoten; } Knoten::~Knoten() {     std::for_each(_children.begin(), _children.end(), loeschen);     _children.clear(); // Vorsicht ist besser als Nachsicht } Man beachte, dass in der Implementations-Datei kein static vor der loeschen-Funktion steht (das hätte hier eine ganz andere Bedeutung), sondern nur in der Header-Datei.

Funktioniert es jetzt?

RE: c++ Vector aus Pointern 2009-02-28 12:42
Fred
Wenn Du Boost verwendest, kannst Du das ganze auch etwas funktionaler betrachten, dann brauchst Du die statische Funktion loeschen nicht mehr:
#include <boost/lambda/lambda.hpp> #include <boost/lambda/bind.hpp> #include <boost/lambda/construct.hpp> using namespace boost::lambda; Knoten::~Knoten() {     std::for_each(_children.begin(), _children.end(), bind(delete_ptr(), _1));     _children.clear(); // Vorsicht ist besser als Nachsicht }
Alternativ kannst Du auch BOOST_FOREACH verwenden, das ist deutlich einfacher:
#include <boost/foreach.hpp> Knoten::~Knoten() {     BOOST_FOREACH(Knoten* k, _children) delete k;     _children.clear(); // Vorsicht ist besser als Nachsicht }
Oder Du verwendest referenzzählende Zeiger, dann passiert das Löschen automatisch, d.h. Du musst gar keinen Destruktor mehr schreiben:
#include <boost/shared_ptr.hpp> class Knoten {     // ...     std::vector<boost::shared_ptr<Knoten> > _children; public:     // ... };
Du siehst, es gibt in C++ wie immer sehr viele Möglichkeiten, ein und dasselbe zu tun.

RE: c++ Vector aus Pointern 2009-03-01 09:56
Anonymer User
Oder Du verwendest referenzzählende Zeiger, dann passiert das Löschen automatisch, d.h. Du musst gar keinen Destruktor mehr schreiben:
#include <boost/shared_ptr.hpp> class Knoten {     // ...     std::vector<boost::shared_ptr<Knoten*> > _children; public:     // ... };
Du siehst, es gibt in C++ wie immer sehr viele Möglichkeiten, ein und dasselbe zu tun.

Es ist wahrscheinlich nur ein Flüchtigkeitsfehler, aber einer mit schwerwiegenden Folgen.
Bei shared_ptr sollte hier der Typ nicht Knoten* sondern Knoten sein.
Also:
[code|
std::vector<boost::shared_ptr<Knoten> > _children;
[/code|
Denn sonst wird nur der Zeiger gelöscht und nicht der Knoten.
Der Vollständigkeit wegen möchte ich noch hinzufügen, dass man shared_ptr auch durch #include <memory> und dann mit std::tr1::shared_ptr ansprechen kann.

RE: c++ Vector aus Pointern 2009-03-01 10:05
Fred
std::vector<boost::shared_ptr<Knoten*> > _children;
Es ist wahrscheinlich nur ein Flüchtigkeitsfehler

std::vector<boost::shared_ptr<Knoten> > _children;
Vielen Dank, ist korrigiert.