Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

Hallo, ich mal wieder ... :D

ich möchte, daß eine Funktion einen Vektor zurückgibt, also ungefähr so:

vector<string> meineFunktion() {

vector<string> meinVektor;

...

return meinVektor;

}

So weit so gut, aber irgendwie will das nicht. Warum? Müßte doch eigentlich gehen, oder?

Geschrieben

Meine persönliche Meinung dazu:

Mit Call by Reference hast du viel weniger Sorgen :)

<BLOCKQUOTE><font size="1" face="Verdana, Arial, Helvetica, sans-serif">Zitat:</font><HR>

#include <iostream>

#include <vector>

#include <string>

template <class T>

int function(T& container)

{

typename T::iterator pos;

int vector_size = container.size();

for(int i = 0; i<vector_size; ++i)

{

cout << container << endl;

}

return(0);

}

int main()

{

vector<string> MeinVector;

MeinVector.push_back("Alles ");

MeinVector.push_back("klar ?");

function(MeinVector);

exit(0);

}

Geschrieben

Man kann Vektoren scheinbar nicht als Rückgabetyp verwenden - ich bekomme auch immer Fehlermeldungen, probiere aber mal weiter und wühl mich noch durch ein paar Bücher. Entweder man arbeitet mit Referenzen, globalen Vektoren oder vielleicht die beste Lösung: Eine Klasse diesen Vektor als Instanzvariable mitgeben und mit allen notwendigen Funktionen versehen (Copy-Konstruktor, Operatoren, etc.). Diese Objekte sollten problemlos hin- und hergereicht werden könnn. Hier kann man dann auch Friend-Klassen definieren, die dann mit dem Vektor direkt hantieren können. Eventuell (hat aber irgendwie noch nicht geklappt) könnte man mit void* arbeiten und diese static casten (muß ich auch noch austesten) - mal sehen. Eventuell sind solche Vektoren als Member-Variablen public zu machen. Also ich lerne auch erst mit der STL umzugehen und deshalb bin ich da gerade ziemlich hinterher - ist ja schon wichtig zu wissen. Es sind nicht allzu viel Leute da draußen, die sich mit der STL intensiv befassen, doch hier kann halt C++ besonders seine Muskeln zeigen und beschleunigter Code ist garantiert. Das Push_back muß ich mir auch nochmal anschauen, denn das war auch ziemlich wichtig, falls (wenn ich mich recht erinnere) Bereichsüberschreitungen von Containern mit eigenen Allokatoren gemacht werden. Ist ja auch ein ziemlich interessantes Thema.

Ich hatte auch noch vergessen zu sagen, daß vector<dingsbums> meinvektor(x); die Größe x der leeren im Voraus allozierten Einträge vom Typ dingsbums mitgegeben werden. Also x=10 bedeutet es wird grundsätzlich Speicher für 10 dingsbums reserviert. Ist Dieser gefüllt werden die nächsten 10 im Speicher angefordert und der Erste belegt.

<FONT COLOR="#a62a2a" SIZE="1">[ 18. September 2001 23:16: Beitrag 5 mal editiert, zuletzt von Crush ]</font>

Geschrieben

Interessantes Thema hier. ;)

@Crush, Poldi

Bei mir funktioniert es:

#include <iostream>

vector<string> foo();

vector<string> foo() {

vector<string> vi(10);

vi[3]="pillepalle";

vi[5]="pollepulle";

return vi;

}

int main()

{

vector<string> vj(10);

vj=foo();

cout << vj[3] << vj[5]<< endl;

cout << vj.size();

return 0;

}

liefert ganz brav die Ausgabe "pillepallepollepulle" und "10".

@multimac

Klar uebergibt man normalerweise Referenzen. Interessant ist aber hier die Frage, warum sich bei Poldi Probleme ergeben, wenn er als return-value einen vector liefert. Ansonsten: Bis morgen. ;-)

Uli

Geschrieben

EisenUli:

Ein Problem hat diese Lösung allerdings. Der erstellte Container aus der "foo"-Funktion wird beim "return" komplett gekopiert. Ich habe mir gerade folgendes Programm geschrieben, das mit Pointern und Templates arbeitet.

<BLOCKQUOTE><font size="1" face="Verdana, Arial, Helvetica, sans-serif">Zitat:</font><HR>

#include <iostream>

#include <vector>

#include <string>

template <class T>

T * function2()

{

T *myvector = new T;

myvector->push_back("Compiliert mit");

myvector->push_back("gcc 2.95.3 .");

return myvector;

}

template <class T>

int function(T& container)

{

typename T::const_iterator pos;

int vector_size = container.size();

for(int i = 0; i<vector_size; ++i)

{

cout << container << endl;

}

return(0);

}

int main()

{

vector<string> *Box = function2<vector< string > >();

function(*Box);

exit(0);

}

Geschrieben

habt erbarmen mit mir, ich kann doch gar kein c++ ... :D:D

den kram mit den templates kann ich noch nicht mal lesen. ich war zwar auf ner java schulung, aber irgendwie scheint mir das nicht wirklich zu helfen ...

aber danke an eisen uli, ich habs nochmal versucht und jetzt läufts, vielleicht war ich gestern schon zu gestreßt um denken zu können ... :D

mal ne andere frage:

wenn es methoden wie vector.insert() oder vector.push_back() und so gibt, dann gibt es doch auch sicherlich methoden, um elemente wieder auszulesen, oder? da ich nie weiß, wie groß die drecksdinger werde, ist der direktzugriff ohne prüfung gefäääährlich, daher denke ich, daß es eine methode mit prüfung schon gibt, oder?

danke für eure hilfe, ihr habt alle einen nervenretter orden verdient!! :D:D

fröhlichst,

eure poldi

Geschrieben

@poldi:

<BLOCKQUOTE><font size="1" face="Verdana, Arial, Helvetica, sans-serif">Zitat:</font><HR> da ich nie weiß, wie groß die drecksdinger werde, ist der direktzugriff ohne prüfung gefäääährlich, daher denke ich, daß es eine methode mit prüfung schon gibt, oder?

Geschrieben

<BLOCKQUOTE><font size="1" face="Verdana, Arial, Helvetica, sans-serif">Zitat:</font><HR>Original erstellt von captain haddock:

<STRONG>@poldi:

Ja, schau mal was du zu iteratoren findest, außerdem gibt es zusätzlich zu [] eine Zugriffsmethode mit Prüfung, die meines Wissens elementAt(int pos) heißt.

</STRONG>

Geschrieben

So Poldi: Dies ist eine einfachere Lösung ohne Templates einmal mit static und einmal mit new:

vector<string>* getvec()

{

static vector<string> gv;

// mit dem Static sollte es keine Probleme bei versehentlich erneutem Aufruf geben

gv.insert(gv.end(),"Erster Satz");

gv.insert(gv.end(),"Zweiter Satz");

gv.insert(gv.end(),"Dritter Satz");

return &gv;

}

vector<string>* getvec2()

{

vector<string>*pvec=new vector<string>; // jedesmal ein neuer Vektor

pvec->insert(pvec->end(),"Pvecs Erster Satz");

pvec->insert(pvec->end(),"Pvecs Zweiter Satz");

pvec->insert(pvec->end(),"Pvecs Dritter Satz");

return pvec;

}

void Vektortest()

{

string x,y,z;

vector<string>*pvj=getvec();

x=pvj->at(0); // über at() kein Problem

y=pvj->at(1);

z=pvj->at(2);

//z=pvj->[2]; // klappt so nicht mehr (obwohl er eigentlich sollte)

//z=*pvj[2]; // und so auch nicht

pvj=getvec2();

x=pvj->at(0);

y=pvj->at(1);

z=pvj->at(2);

delete pvj; // auf keinen Fall vergessen!

}

Gestern habe ich das alles nicht hinbekommen aus einem guten Grund: Man muß den at() Operator anscheinend verwenden. Über den []-Operator konnte ich nur Fehler erzeugen und sonst nix. Vielleicht weiß ja Multimac, wie man das hinbekommen könnte falls überhaupt. Templates sind etwas wichtiges um Zeit und Codezeilen zu sparen, aber man kann im Zweifelsfall auch anders ans Ziel gelangen. Die STL ist jedoch eine pure Template-Klasse mit 1000 Inline-Funktionen und man sollte wenigstens wissen, wie man die Templates einsetzt. Auch Stroutrup meint es wäre am Besten die ganzen Container in Klassen als Elementvariablen zu kapseln (erscheint mir auch sinnvoller als sie hin- und herzureichen oder gar rum- und numzukopieren - abgesehen davon, daß die Daten eigentlich gar nicht geschützt werden). Es gibt aber auch noch die Möglichkeit sich "künstliche Templates" als Makros zu definieren (#define) dann geht aber die Laufzeitpolymorphie zugrunde, weil praktisch vor dem Compilieren im Sourcecode Zeilen erzeugt werden (und ein erfahrener Programmierer hat mir gesagt, daß man das nur noch für kleine Sachen - am besten aber überhaupt nicht mehr nach den Programmierrichtlinien verwenden sollte). Ihn hat bei Templates das Debuggen ein wenig erschreckt und deshalb verwendet er diese nur, wenn es wirklich sein muß. Interessant sind auch Funktionstemplates, allerdings erlauben die es aus Compilergründen nicht virtuell zu sein (schade).

<FONT COLOR="#a62a2a" SIZE="1">[ 19. September 2001 12:04: Beitrag 1 mal editiert, zuletzt von Crush ]</font>

Geschrieben

ich halte die erste funktion für wenig sinnvoll. dabei habe ich keine chance diese zweimal aufzurufen und den selben effekt zu erzielen.

<FONT COLOR="#a62a2a" SIZE="1">[ 19. September 2001 12:23: Beitrag 4 mal editiert, zuletzt von maddin ]</font>

Geschrieben

das mit dem elementAt muß doch so aussehen, oder?:

---------------------------------

string test;

vector<string> myVek;

...

test = myVek.elementAt(20);

...

---------------------------------

was ist denn er rückgabetyp von elementAt? doch der typ des vektors, oder?

naja mein dummer compiler mag das nicht, der sagt mir no matching function ....

Geschrieben

@Maddin: Sollte ja auch nur eine Alternative zum Klassenverpacken sein, weil ich´s halt vorher mal angesprochen habe habe ich es auch gleich mit reingenommen. Man kann das ganze ja auch als globales Array verwenden.

@Poldi: Huhu das Ding heißt nicht elementAt() sondern nur at() schau doch mal oben in den Source. Da habe ich halt anstatt den . einen -> weil´s halt Zeiger sind.

Mit Deinem Source:

string test;

vector<string> myVek;

test = myVek.at(20);

Ich weiß ja nicht welchen Compiler Du verwendest, aber wenn Du den . beim Studio benutzt werden alle verfügbaren Funktionen dargestellt und da findet man auch nur das .at()!

no matching function heißt ja auch: keine passende Funktion gefunden (existiert so halt nicht unter diesem Namen oder mit diesen Parametern)!

Geschrieben

nein, das tuts auch nicht.

ich programmier unter unix mit dem g++ ... das mit dem at scheint was vc++ spezifisches zu sein.

in meiner literatur hab ich folgendes gefunden:

Object elementAt(int index)

was ist denn Object für ein Datentyp? Hat doch irgendwas mit Klassen und so zu tun, oder?

aber selbst wenn ich die funktion aufrufe, ohne den rückgabewert irgendwohin zu lenken, compiliert der nicht. menno.

ich hab mir jetzt ne eigene funktion dafür geschrieben ...

danke leute, ihr habt mir sehr weitergeholfen ... :o)

mfg -poldi-

Geschrieben

<BLOCKQUOTE><font size="1" face="Verdana, Arial, Helvetica, sans-serif">Zitat:</font><HR>Original erstellt von Poldi:

<STRONG>

Object elementAt(int index)

was ist denn Object für ein Datentyp? Hat doch irgendwas mit Klassen und so zu tun, oder?

</STRONG>

Geschrieben

<BLOCKQUOTE><font size="1" face="Verdana, Arial, Helvetica, sans-serif">Zitat:</font><HR>Gestern habe ich das alles nicht hinbekommen aus einem guten Grund: Man muß den at() Operator anscheinend verwenden. Über den []-Operator konnte ich nur Fehler erzeugen und sonst nix.

Geschrieben

"Beim Stöbern im Netz habe ich vorhin folgenden Satz gefunden: "Never return containers! Return iterators!" :-) "

Klingt vernünftig. Container sollten meiner Meinung nach immer irgenwo fest verankert sein und nicht bewegt werden. Zugriffe von außen sollten am besten über eigens dafür vorgesehene Methoden ablaufen, damit kein Unfug damit angestellt werden kann.

"Wir haben doch noch einen anderen Template-Guru hier, ich glaube Crush... "

Ich sehe mich schon im Jogasitz über meinem Nagelbrett schweben (grins)!

Nein, ernsthaft: Ich habe selber noch nicht eine eigene Template-Klasse erstellt - bin doch selbst noch beim Lernen!

Aber so unheimlich kompliziert ist´s wirklich nicht wie man´s gerne darstellt - wenn man nur versteht, wie´s geschrieben werden soll (Platzhalter für den Datentyp: Das ist doch so extrem abstraktes Denken nun auch wieder nicht).

In billigem C-Code habe ich schon wesentlich abstrakteres gesehen (rekursive Lösung der Türme von Hanoi oder (auch rekursiv) das 8-Damen-Problem zum Beispiel hab ich bis heute noch nicht gerafft). Rekursion in der Praxis wäre auch mal einen Thread wert.

Ich persönlich halte Multimac für den Erfahrensten dem ich hier im Forum bisher begegnet bin! (ok, vielleicht noch 1-2 andere kann man noch dazunehmen)

Geschrieben

Ach soooo ist das! Und ich dachte schon, daß der []-Operator als protected deklariert ist und deshalb keine Referenzzugriffe erlaubt! Man soll wohl lieber mit dem Iterator oder at() arbeiten, dann gibt´s auch keinen Ärger.

Geschrieben

<BLOCKQUOTE><font size="1" face="Verdana, Arial, Helvetica, sans-serif">Zitat:</font><HR>Original erstellt von Crush:

<STRONG>Ach soooo ist das! Und ich dachte schon, daß der []-Operator als protected deklariert ist und deshalb keine Referenzzugriffe erlaubt! Man soll wohl lieber mit dem Iterator oder at() arbeiten, dann gibt´s auch keinen Ärger.</STRONG>

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...