Technician Geschrieben 8. April 2002 Geschrieben 8. April 2002 Hallo, ich hab hier ein kleines, aber feines Problemchen: Das Objekt "Kunde" hat ein Attribut seinName char seinName[30]; auf das mit char GetName(){return seinName[2];}; zugegriffen werden soll. Klar, hier wird nur der dritte Buchstabe zurückgeliefert - um alles zurückzugeben, müsste ich irgendwie als Rückgabetyp statt char schreiben char[] oder ähnliches, aber wenn diese eckigen Klammern irgendwo beim Rückgabetyp stehen, mag das der Compiler nicht so gern... :confused: Mit char* statt char[] wäre das Problem leicht zu beheben - aber nein, es muss ja unbedingt ein char-Array sein... Bitte, bitte sagt mir, ob eine Methode wirklich ein char-Array zurückliefern kann (und wenn, wie?!) - oder hat mich da mein C++Dozent tüchtig veräppelt (von dem stammt nämlich der "Programmierauftrag", wo das mit dem Array vorkommt...)?!?!?!!? Gruß, die leicht verzweifelte und auf Hilfe hoffende Technician Zitieren
nic_power Geschrieben 8. April 2002 Geschrieben 8. April 2002 char * ist schon richtig: char *GetName() { char *name; [... viel code ...] return name; } Alternativ kannst Du auch schreiben: char *getName() { char name[]; return name; } Zitieren
Klotzkopp Geschrieben 8. April 2002 Geschrieben 8. April 2002 Original geschrieben von nic_power char *getName() { char name[]; return name; } [/code] Die Adresse einer Variablen zurückgeben, die gleich nach dem return freigegeben wird? Gar nicht gut... Zitieren
nic_power Geschrieben 8. April 2002 Geschrieben 8. April 2002 Wo siehst Du denn da die Adresse einer Variablen, die nach dem Return freigegeben wird? Allerdings hast Du insofern recht, dass char [] nur in Funtionsparametern verwendet werden kann, da war ich wohl etwas zu voreilig (das zweite Beispiel wird nicht kompiliert). Nic Zitieren
Klotzkopp Geschrieben 8. April 2002 Geschrieben 8. April 2002 Original geschrieben von nic_power Wo siehst Du denn da die Adresse einer Variablen, die nach dem Return freigegeben wird? Sorry, selektive Wahrnehmung, ich dachte, da wäre eine Zahl zwischen den eckigen Klammern. Aber was anderes: Schluckt das Dein Compiler? Meiner weiß nicht, wie er einen Array der Größe Null anlegen soll. Er tuts wohl nicht Zitieren
nic_power Geschrieben 8. April 2002 Geschrieben 8. April 2002 Noe, das wird so kein Compiler nehmen. Ich hatte mich geirrt, die schreibweise "char bla[]" ist nur bei Funktionsparametern erlaubt. Nic Zitieren
Technician Geschrieben 8. April 2002 Autor Geschrieben 8. April 2002 Hi nic_power! Original geschrieben von nic_power char * ist schon richtig: char* is zwar richtig, aber das durfte ich ja nicht verwenden (laut Aufgabenstellung)... und ich vermute jetzt SEEEEHR stark, dass das ein fieser Trick ist Zitieren
nic_power Geschrieben 8. April 2002 Geschrieben 8. April 2002 In C oder C++? In C geht das nicht, allerdings gibt es in C++ eine (schlechte und ineffiziente) Methode um auch Arrays zurueckzugeben. Nic Zitieren
Technician Geschrieben 8. April 2002 Autor Geschrieben 8. April 2002 Original geschrieben von nic_power In C oder C++? In C geht das nicht, allerdings gibt es in C++ eine (schlechte und ineffiziente) Methode um auch Arrays zurueckzugeben. Nic in C++ Zitieren
nic_power Geschrieben 8. April 2002 Geschrieben 8. April 2002 Ist der Prototyp fuer GetName vorgegeben oder solltest Du nur einen Member schreiben, der eine Kopie des namens zurueck liefert? Nic Zitieren
Technician Geschrieben 8. April 2002 Autor Geschrieben 8. April 2002 Original geschrieben von nic_power Ist der Prototyp fuer GetName vorgegeben oder solltest Du nur einen Member schreiben, der eine Kopie des namens zurueck liefert? Nic Ich hab char seinName[30]; und ich soll eine Methode - nicht mehr, nicht weniger - der Art char GetName(){return seinName[0];}; schreiben (ja, ich weiß, die Methode die ich jetzt da hingeschrieben habe liefert nur ein Element...) Zitieren
DBO Geschrieben 8. April 2002 Geschrieben 8. April 2002 Original geschrieben von Technician Ich hab char seinName[30]; und ich soll eine Methode - nicht mehr, nicht weniger - der Art char GetName(){return seinName[0];}; schreiben (ja, ich weiß, die Methode die ich jetzt da hingeschrieben habe liefert nur ein Element...) wahrscheinlich werde ich jetzt wieder eines besseren belehrt, aber wenn du doch schreibst char *GetName(){return &seinName[0]; bekommst du doch die Adresse von ersten Element zurück und kannst dann mittels [] auf die einzelnen Elemente zugreifen, oder lieg ich jetzt ganz falsch? Zitieren
nic_power Geschrieben 8. April 2002 Geschrieben 8. April 2002 Etwas aufwendiger ist das schon, da er ja tatsaechlich den kompletten Array und nicht die Adresse des Arrays zurueckliefern soll. D.h. Du musst eine 1:1 Kopie des namens liefern, keinen Pointer. Realisieren laesst sich sowas in C++ entweder ueber temporaere Objekte oder ueber das Ueberladen des [] Operators. Das Ganze duerfte aber ziemlich fummelig werden und ist in diesem Fall nur ueber Umwege realisierbar. Nic Zitieren
Saber_Rider Geschrieben 9. April 2002 Geschrieben 9. April 2002 Also ich denke auch, dass das geht. Ich hab das schon mal irgendwo gelesen. Aber ich könnte mir beim besten Willen nicht vorstellen wozu man das brauchen sollte. Schließlich ist der Normalweg, dass man sich einen Pointer zurückliefern lässt. Es bleibt sich ja auch ganz egal. Ein Pointer ist ein Zeiger auf etwas, das irgendwo im Speicher ist. Und man greift halt auf den Inhalt der Variable über den Pointer zu. Oder hat Dein PC keinen Arbeitsspeicher? *sfg* Just a Joke! Zitieren
Technician Geschrieben 9. April 2002 Autor Geschrieben 9. April 2002 @Saber_Rider es funktioniert jetzt: Rückgabe über char* Kunde::GetName() { return seinName; }; //seinName ist in Kunde als char seinName[30] angelegt Set über void Kunde::SetName(char n[30]) { strcpy(seinName, n); }; jetzt gibt's keine Probleme mehr; danke trotzdem (besser gesagt, gerade deshalb ) an alle! btw: Weißt du, wer ich bin?! :D Technician Zitieren
nic_power Geschrieben 9. April 2002 Geschrieben 9. April 2002 Oeh, naja. GetName liefert immer noch einen Pointer zurueck. Nic Zitieren
Saber_Rider Geschrieben 9. April 2002 Geschrieben 9. April 2002 Fix, jetzt hätte ich Dir gerade so schönen guten alten C-Source zusammengehackt. Na ja, ich poste ihn trotzdem: /*******************************/ #include <stdio.h> void getName(char *value); int main() { char seinName[30]; getName(seinName); printf("Ergebnis: %s\n", seinName); } void getName(char *value) { strcpy(value, "Manfred Mustermann"); } /*******************************/ Ist zwar C und ich hab jetzt mal nicht extra irgendwelche Objekte erzeugt, aber der Sinn und Zweck ist der selbe und funktionieren tut´s auch. Sicher weiss ich wer Du bist @ Technician Du arbeitest 5 Stockwerke über mir, gehörst der selben Firma wie ich an, hast dunkle Haare, eine Brille und gehst mit mir in die selbe Berufschulklasse. *sfg* Zitieren
Technician Geschrieben 9. April 2002 Autor Geschrieben 9. April 2002 Original geschrieben von Saber_Rider Fix, jetzt hätte ich Dir gerade so schönen guten alten C-Source zusammengehackt. Na ja, ich poste ihn trotzdem: /*******************************/ #include <stdio.h> void getName(char *value); int main() { char seinName[30]; getName(seinName); printf("Ergebnis: %s\n", seinName); } void getName(char *value) { strcpy(value, "Manfred Mustermann"); } /*******************************/ Ist zwar C und ich hab jetzt mal nicht extra irgendwelche Objekte erzeugt, aber der Sinn und Zweck ist der selbe und funktionieren tut´s auch. das OOP ist ja auch nicht wichtig dafür; war ja nur mein Ausgangspunkt is das gleiche wie meine Version, danke trotzdem!!! (denn wär ich nicht selber draufgekommen, dann bräucht ich das jetzt *sfg* ) Sicher weiss ich wer Du bist @ Technician Du arbeitest 5 Stockwerke über mir, gehörst der selben Firma wie ich an, hast dunkle Haare, eine Brille und gehst mit mir in die selbe Berufschulklasse. *sfg* yep! Zitieren
Crush Geschrieben 9. April 2002 Geschrieben 9. April 2002 Wenn ein Zeiger zurückgegeben werden soll, warum macht reserviert ihr dann nicht einfach mit NEW neuen Speicher, befüllt ihn und gebt dann einen Zeiger darauf zurück? Der Speicher muß halt später nochmal von außerhalb freigegeben werden. Zitieren
BioLex Geschrieben 9. April 2002 Geschrieben 9. April 2002 hab gedacht das Array soll auf den Stack... Zitieren
Crush Geschrieben 9. April 2002 Geschrieben 9. April 2002 Daten vom Stack sind TEMPORÄR... das geht nicht. Man muß einen Kopiervorgang starten (wie oben auf eine Referenz) oder eben mit einem static-Array arbeiten oder halt etwas mit NEW vom Heap reservieren und die Adresse weiterreichen und bei Klassen funktioniert der ganze Spaß über die Operatoren. Eine andere Methode wüßte ich jetzt wirklich nicht, aber vielleicht gibt´s ja doch noch irgendwas anderes. Das Problem ist, wer die Verantwortung für die Freigabe von Speicher hat und wie lange die Daten existieren und verwendet werden (Thema: Dangling Pointer). Eine Regel ist, daß alle Daten eines Objekts das Objekt selbst über den Destruktor verwalten muß. Übergabe von Referenzen bedeuten nur, daß die verwendenden Funktionen sich um die Daten nicht weiter zu kümmern brauchen. Egal wie man das Problem lösen will - man muß irgendwie immer mit einer Referenz hantieren - entweder die von der Quelle oder die vom Ziel. Ich bin von einem Array aus Strings ausgegangen ... da wäre das so wohl kaum möglich (muß ich mal testen). Zitieren
Orffi Geschrieben 9. April 2002 Geschrieben 9. April 2002 Wenn man sich nicht einig wird, wer den Speicher wieder freigibt, dann kann man ja einen Autopointer (auto_pr) aus <memory> benutzen. Diesen gibt es nur in C++, aber wenn ich das richtig sehe, darf es ja C++-Code sein. Dieser auto_ptr sorgt dafür, daß der Destruktor aufgerufen wird, wenn man keine Referenz mehr darauf hat. Es ist aber bei weitem noch kein Smartpointer (was so etwas wie ein Pointer mit Garbage Collector wäre.) Es fehlt noch eine ganze Menge dazu. Wenn es von Interesse ist, also nicht zu weit vom Thema wegführt, kann ich ein paar Zeilen dazu schreiben. HTH Jan Zitieren
nic_power Geschrieben 9. April 2002 Geschrieben 9. April 2002 Hallo, Man kann bei ungeschickter Programmierung auch den Compiler dazu bringen, temporaere Objekte anzulegen: class Complex { [...] friend Complex operator+(const Complex&, const Complex &); } Complex c1; Complex c4=c2+c3; c1=c2+c3; Sofern man nur einen Operator fuer die Addition und den Default-Operator fuer die Zuweisung verwendet, wird im obigen Beispiel vom Compiler ein temporaeres Objekt angelegt, da die Zuweisung nur dann aufgeloest werden kann, wenn auch ein neues Objekt erzeugt wird. Das Problem an der Stelle ist, dass der Compiler nicht weiss, ob der Additions-Operator c1 modifiziert und damit Werte ueberschreibt die nochmals benoetigt werden, bevor die Addition abgeschlossen ist. Aus diesem Grund legt er ein neues (temporaeres) Objekt an, in dem die Werte zwischengespeichert werden und welches nach Abschluss der Addition nach c1 kopiert wird. Daher sollte man Operatoren wie "+=, -=" usw. ebenfalls ueberladen. Gerade bei Programmen die komplexe Klassen verwenden kann es zu massiven Geschwindigkeitseinbußen kommen, die man bei geschickter Programmierung vermeiden kann. Nic Zitieren
maxim_42 Geschrieben 10. April 2002 Geschrieben 10. April 2002 Wenn in C++ programmiert werden soll, und die Rückgabe eines Pointers ok ist, kann man das Ganze doch recht einfach halten: #include <iostream> #include <string.h> class Kunde{ private: char m_name[30]; public: Kunde(const char* const name); const char* const name() const; void name( const char* const newName); };//class Kunde Kunde::Kunde(const char* const name){ strcpy(m_name, name); } const char* const Kunde::name() const{ return m_name; } void Kunde::name( const char* const newName){ strcpy(m_name, newName); } int main( void ){ Kunde einKunde("Heinz Dau"); std::cout<<"Der Kunde "<<einKunde.name()<<" hat jetzt "; einKunde.name("Heinz Gau"); std::cout<<"den Namen "<<einKunde.name()<<std::endl; return 0; } Zitieren
maxim_42 Geschrieben 10. April 2002 Geschrieben 10. April 2002 @orfi Wie unterscheidet sich den ein auto_ptr von einem pointer mit "garbage collector"? Arbeitet ein garbage collector nicht so, dass er für Objekte die nicht mehr erreichbar sind den Destruktor aufruft? Und tut das nicht auch der auto_ptr für sein Objekt? sehr interessiert... max Zitieren
Empfohlene Beiträge
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.