Forum: PC-Programmierung String übergenen


von Kolos (Gast)


Lesenswert?

Hallo momentan mach ich das so

void setname(const char *c = "")
{strcpy(name,c);}
...
char name[20];

oder so

void setNEWname (const char *c = "")
{newnamen = new char[strlen(c) + 1];
strcpy(newnamen,c);}
...
char *newnamen;


aber da bringt der Combiler immer ne Warnung
gibts da noch bessere Medtoden

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> aber da bringt der Combiler immer ne Warnung

Schön, daß Du die für Dich behältst. Da Du auch nicht sagst, was Du 
anstellen willst, kann nur die Glaskugel befragt werden.

a) es handelt sich offensichtlich um C++ - Code.

b) Im ersten "Beispiel" (ich bin jetzt mal gutmütig und nenne den Rotz 
so) benutzt Du die Variable name, bevor Du sie deklariert hast.

c) Dasselbe stellst Du im zweiten "Beispiel" mit newnamen an.

von Rene H. (Gast)


Lesenswert?

Gibt es einen Grund, dass Du nicht STL benutzt? Dann wäre es wesentlich 
einfacher.

von Rene H. (Gast)


Lesenswert?

Meine Frage rührt daher, das ich nicht verstehen kann weshalb so viele 
in C++ c programmieren....

von Kolos (Gast)


Lesenswert?

Das ganze ist in einer Klasse und sieht dann zb so aus

class String
{
public:
    void setNEWname (const char *c = "")
         {newnamen = new char[strlen(c) + 1];
          strcpy(newnamen,c);}


private:
   char *newnamen;
};


String meinname;
meinname.setNEWname("Franz");


und da bringt er immer ne Warnung
strcpy': This function or variable may be unsafe

von Random .. (thorstendb) Benutzerseite


Lesenswert?

weil der compiler C++ heisst und die dann meinen, sie könnten C++ :-)

von Random .. (thorstendb) Benutzerseite


Lesenswert?

unter MS VC gibt es diese _s funktionen, die sollen save sein. Meist 
spuckt er da ne Warning aus für z.B. sprintf.
Ist dein SrcString nicht am richtigen Ende mit '\0' terminiert (also 
erst irgendwann durch zufall) oder zu lang schreibst du in Speicher, wo 
dir dann das OS auf die Finger haut (oder sollte).

Daher "unsave".

Aber ein C-Programmierer sollte wissen, was er tut. Wenn nicht, lerne 
Java :-)

VG,
/th.

von Random .. (thorstendb) Benutzerseite


Lesenswert?

so gehts:
1
// header:
2
class String
3
{
4
public:
5
    void SetNewName (const char *c = "");
6
7
8
private:
9
   char *newnamen;
10
};
11
12
// Cpp-file:
13
void String::SetNewName (const char *c = "")
14
{
15
 newnamen = new char[strlen(c) + 1];
16
 strcpy(newnamen,c);
17
}

Man beachte hier auch das richtige CamelCase.
Die Klassendefinitionen kommen in den Header, damit die in anderen 
Modulen richtig #include-d werden können (sonst gehts schief).

Die Methoden kommen in das cpp file (#include "header.h" nicht 
vergessen!)

VG,
/th.

von Severino R. (severino)


Lesenswert?

Random ... schrieb:
> unter MS VC gibt es diese _s funktionen, die sollen save sein. Meist
> ...
> Daher "unsave".

To save or not to save, that's the question.

Aber das Ding heisst safe, wie der Compiler auch schon richtig schreibt.

von Karl H. (kbuchegg)


Lesenswert?

Random ... schrieb:

> Aber ein C-Programmierer sollte wissen, was er tut. Wenn nicht, lerne
> Java :-)

:-)
Es reicht völlig, wenn er C++ programmiert, wenn er einen C++ Compiler 
benutzt. Aber auch das wurde schon angesprochen :-)

von Random .. (thorstendb) Benutzerseite


Lesenswert?

**arg** Edit-Zeit zu kurz!

so gehts:
1
// header:
2
class String
3
{
4
public:
5
    String();
6
    ~String();
7
    void SetNewName (const char *c = "");
8
9
10
private:
11
   char *newnamen;
12
};
13
14
// Cpp-file:
15
16
String::String()
17
{
18
  // Konstruktor
19
}
20
21
String::~String()
22
{
23
  // Destruktor
24
}
25
26
27
void String::SetNewName (const char *c = "")
28
{
29
 newnamen = new char[strlen(c) + 1];
30
 strcpy(newnamen,c);
31
}

Man beachte hier auch das richtige CamelCase.
Die Klassendefinitionen kommen in den Header, damit die in anderen 
Modulen richtig #include-d werden können (sonst gehts schief).

Die Methoden kommen in das cpp file (#include "header.h" nicht 
vergessen!)

VG,
/th.

von Random .. (thorstendb) Benutzerseite


Lesenswert?

Severino R. schrieb:
> Random ... schrieb:
>> unter MS VC gibt es diese _s funktionen, die sollen save sein. Meist
>> ...
>> Daher "unsave".
>
> To save or not to save, that's the question.
>
> Aber das Ding heisst safe, wie der Compiler auch schon richtig schreibt.

whoops :-)

von Karl H. (kbuchegg)


Lesenswert?

Random ... schrieb:
> so gehts:

Brauch ich dir wahrscheinlich auch nicht sagen:
So einfach wirst du diese Warnung vom MS-Compiler nicht los.
Aber in der Warnung vom Compiler steht auch drinnen, wie man sie mit 
einem #define abschalten kann :-)

von Random .. (thorstendb) Benutzerseite


Lesenswert?

"so gehts" war nicht auf die Warnung, sondern auf richtiges / 
richtigeres C++ bezogen. Damits auch mit Modulen klappt, sonst hatter 
gleich nach seiner Warning nen Error auf der Matte stehen :-)

> wie man sie mit
> einem #define abschalten kann :-)
megaLOL
Erinnert mich irgendwie an Lint. Will Lint nicht, will ich wohl, daher 
schalten wir's ab :-)


VG,
/th.

von Karl H. (kbuchegg)


Lesenswert?

Random ... schrieb:
> "so gehts" war nicht auf die Warnung, sondern auf richtiges /
> richtigeres C++ bezogen.

Na ja.
Wenn wir danach gehen, dann hat auch deine letzte Version noch einigen 
Nachholbedarf :-)

Das fängt beim Constructor, Copy Constructor, Operator=, Destruktor an 
und hört beim wegfallen des Defaultarguments in der Funktionsdefinition 
auf.

(Aber das soll der OP alleine herausfinden. Oder am besten gleich 
richtiges C++ programmieren und std::string benutzen :-)

von Kolos (Gast)


Lesenswert?

void setNEWname (const char *c = "")


um mal beim Thema zu bleiben unser Prof stellt in der Prüfung

zb diesen Rumpf (siehe oben) zur Verfügung und dann heists machmal

mit der std::string haben wir bei den Übungen nichts gemacht
deshalb denke ich nicht das das Überhaupt in der Prüfung drankommt

von Karl H. (kbuchegg)


Lesenswert?

Kolos schrieb:
> void setNEWname (const char *c = "")
>
>
> um mal beim Thema zu bleiben unser Prof stellt in der Prüfung
>
> zb diesen Rumpf (siehe oben) zur Verfügung und dann heists machmal

wenn du in deiner Funktion dann vor der Allokierung des neuen Speichers 
den Speicher freigibst, auf den newname vorher zeigt, dann hinterlässt 
dein Code auch keine Speicherlöcher :-)
Mehr kannst du mit dem bischen Kontext nicht tun und auch nicht 
erwarten.

Die Warnung ist ein 'Feature' des Microsoft Compilers, von dem die MS 
Leute denken, dass sie C-Code sicherer macht (was sie natürlich nicht 
tut. Ihre sogenannten safe-Versionen können ein grundsätzliches Problem 
der String-Verarbeitung in C nicht beheben. Ich kann immer noch meinen 
Compiler anlügen und ihm sagen meine Targetarea sei größer als sie 
tatsächlich ist)

> mit der std::string haben wir bei den Übungen nichts gemacht
> deshalb denke ich nicht das das Überhaupt in der Prüfung drankommt

Das sollte einem eigentlich zu denken geben.

von Kolos (Gast)


Lesenswert?

Hab da nochmal was im Skript enteckt was mir komisch vorkommt.

Daten Daten::operator=(const Daten &s)
{
   if (this != &s)       // alternat: if (pString != s.pString)
   {                     // nichts tun, falls identisch
      delete [] newnamen;
      newnamen = new char[strlen(s.newnamen) + 1];
      strcpy(newnamen, s.newnamen);
   }
   return *this;
}


so stehts im Skript aber wäre es nicht besser wenn man das so schreibt


delete [] s.newnamen;

von Rene H. (Gast)


Lesenswert?

newnamen ist dann wohl eine Member Variable. Ob Du das Delete auf 
s.newnamen oder auf this->newnamen etc. machst, ist egal.
Aber wenn Du von einem Prof sprichst uns ich mir das so anschaue, ist es 
doch bedenklich was ihr da so gelehrt bekommt.
Sorry, der Zusatz musste sein.

von Rene H. (Gast)


Lesenswert?

Sorry, stimmt nicht. Das if ist ja != :-)
In dem Fall delete s.newnamen oder delete newnamen. Ist egal.

von Kolos (Gast)


Lesenswert?

Ich hab mir ein eigenes Programm geschrieben

und ich bekomm bei diesem delete [] newnamen;
ständig folgende Meldung


Unbehandelte Ausnahme bei 0x657431ea (msvcr90d.dll) in test.exe: 
0xC0000005: Zugriffsverletzung beim Lesen an Position 0xccccccc0.

und ich denk mal das das am delete liegt

von P. S. (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:

>> mit der std::string haben wir bei den Übungen nichts gemacht
>> deshalb denke ich nicht das das Überhaupt in der Prüfung drankommt
> Das sollte einem eigentlich zu denken geben.

Dass man an einer Hochschule noch Grundlagen lernt, statt sich nur auf 
Bibliotheken zu verlassen?

von Random .. (thorstendb) Benutzerseite


Lesenswert?

kannst latürnich nur deleten wenn der auch vorher auf valid speicher 
steht.

Beim debuggen kannste das im MS VC debugger an 0xcccccccc für Vars oder 
0xcdcdcdcd für pointer sehen, oder initialisierst deine Pointer mit 0 
oder NULL und prüfst vor jedem access drauf (fp = fopen z.B. gibt eine 0 
zurück wenns schiefgeht, die kann man abfangen)

VG,
/th.

von Karl H. (kbuchegg)


Lesenswert?

Rene H. schrieb:
> Sorry, stimmt nicht. Das if ist ja != :-)
> In dem Fall delete s.newnamen oder delete newnamen. Ist egal.

Wie kommst du drauf, dass das egal ist?

Du kannst doch nicht einfach dem übergebenen Argument seinen String 
unter dem Hintern wegdeleten!

So wärs richtig (Jedes Zeichen beachten! Auch der Returntyp der FUnktion 
ist wichtig!)
1
Daten & Daten::operator=(const Daten & s)
2
{
3
   if (this != &s)       // alternat: if (pString != s.pString)
4
   {                     // nichts tun, falls identisch
5
      delete [] newnamen;
6
      newnamen = new char[strlen(s.newnamen) + 1];
7
      strcpy(newnamen, s.newnamen);
8
   }
9
   return *this;
10
}

Allerdings wäre die noch bessere Version die hier
1
Daten Daten::operator=(const Daten &s)
2
{
3
  char * tmp = new char[strlen(s.newnamen) + 1];
4
  strcpy( tmp, s.newnamen );
5
  delete [] newnamen;
6
  newnamen = tmp;
7
8
  return *this;
9
}

Die ist dann auch noch Exception-safe.
(Ist ein op= korrekt geschrieben, dann braucht man keine Überprüfung auf 
Self Assignment)

> Aber wenn Du von einem Prof sprichst uns ich mir das so anschaue,
> ist es doch bedenklich was ihr da so gelehrt bekommt.

Wird wohl das übliche sein.
Die Profs die auf der Uni lehren, sollten selbst erst mal einen 
vernünftigen C++ Kurs besuchen.

von Karl H. (kbuchegg)


Lesenswert?

Peter Stegemann schrieb:
> Karl heinz Buchegger schrieb:
>
>>> mit der std::string haben wir bei den Übungen nichts gemacht
>>> deshalb denke ich nicht das das Überhaupt in der Prüfung drankommt
>> Das sollte einem eigentlich zu denken geben.
>
> Dass man an einer Hochschule noch Grundlagen lernt, statt sich nur auf
> Bibliotheken zu verlassen?

Sorry. Aber das hat nichts mit Grundlagen mehr zu tun.
In C++ gibt es eine offizielle String Klasse die genauso vorhanden ist, 
wie eine Dateibehandlung. Mit der sollte man erst mal anfangen, ehe man 
sich selber auf das Niveau der eigenen String Allokierung begibt. Du 
implementierst ja auch deine Dateizugriffe nicht Fetsplattenebene 
selber.

Nur weil C keine vernünftigen Strings kennt, heisst das noch lange 
nicht, dass man daher auch in C++ auf jeglichen Komfort verzichten 
sollte. Vor allen Dingen dann nicht, wenn die entsprechenden C++ Klassen 
aus dem Stand heraus funktionieren.

Wenn man genügend Erfahrung in der Programmierung hat, kann man immer 
noch auf die Details einer eigenen Stringbehandlung eingehen und diese 
implementieren. Aber zum lernen, wie man in C++ programmiert ist die 
(halbherzige) Kentniss einer C-Stringverarbeitung genauso hilfreich, wie 
das lernen von Japanisch wenn man Kisuaheli kann.

Man muss einfach nur akzeptieren, dass die Grundlagen in C++ andere sind 
als in C.

von Karl H. (kbuchegg)


Lesenswert?

Kolos schrieb:
> Ich hab mir ein eigenes Programm geschrieben
>
> und ich denk mal das das am delete liegt

Nein. Das liegt nicht daran.
Das liegt höchst wahrscheinlich daran, dass du newname im Konstruktor 
keinen NULL Pointer verpasst hast.

von Zum (Gast)


Lesenswert?

Also das geht auf jeden Fall delete [] this->newnamen;


wenn du das delete [] s.newnamen;
schreibst löscht du ja den Namen den du kopieren möchtest

von Rene H. (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Rene H. schrieb:
>> Sorry, stimmt nicht. Das if ist ja != :-)
>> In dem Fall delete s.newnamen oder delete newnamen. Ist egal.
>
> Wie kommst du drauf, dass das egal ist?
>
> Du kannst doch nicht einfach dem übergebenen Argument seinen String
> unter dem Hintern wegdeleten!
>

Ja, stimmt natürlich :-). Habe nicht so genau hingeguckt.

von P. S. (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Peter Stegemann schrieb:

>> Dass man an einer Hochschule noch Grundlagen lernt, statt sich nur auf
>> Bibliotheken zu verlassen?
> Sorry. Aber das hat nichts mit Grundlagen mehr zu tun.

Doch, sehr wohl. Denn hier geht's kaum um wirklich spezielles 
String-Wissen, sondern um einfache Set- und Get-Methoden, mit ein 
bisschen allokieren und kopieren. Da auf std::string zu verweisen ist 
kontraproduktiv.

> In C++ gibt es eine offizielle String Klasse die genauso vorhanden ist,
> wie eine Dateibehandlung. Mit der sollte man erst mal anfangen, ehe man
> sich selber auf das Niveau der eigenen String Allokierung begibt.

Beides ist nicht immer vorhanden und auch oft nicht optimal. Gerade 
Dateibehandlung ist in der STL einfach nur noch schraeg, voellig 
unnoetig abstrahiert. Mit ordentlichen File- und Directory-Klassen waere 
der C++-Welt mehr gedient gewesen.

> Du implementierst ja auch deine Dateizugriffe nicht Fetsplattenebene
> selber.

Nicht alles was hinkt, ist ein Vergleich.

> Nur weil C keine vernünftigen Strings kennt, heisst das noch lange
> nicht, dass man daher auch in C++ auf jeglichen Komfort verzichten
> sollte.

Nur weil es fuer C++ std::string gibt, heisst das nicht, dass das 
vernuenftige Strings sind.

> Vor allen Dingen dann nicht, wenn die entsprechenden C++ Klassen
> aus dem Stand heraus funktionieren.

Das tun sie auch nicht immer. Aber das merkt man erst im harten 
Praxisalltag, nicht im Elfenbeinturm.

> Wenn man genügend Erfahrung in der Programmierung hat, kann man immer
> noch auf die Details einer eigenen Stringbehandlung eingehen und diese
> implementieren.

Wo soll denn die Erfahrung herkommen, wenn schon die Stringverarbeitung 
umschifft wird? Strings sind sehr praktisch, um die Tuecken von new, 
delete, Resourcenverwaltung und Pointern zu lernen.

Quatsch ist, erst mal C++ in der Softvariante zu lehren, dem Schueler zu 
vermitteln wie einfach es ist ein dickes Programm zu schreiben und ihm 
dann zuzusehen, wie er mit dem Ding nicht mehr zurecht kommt.

> Aber zum lernen, wie man in C++ programmiert ist die
> (halbherzige) Kentniss einer C-Stringverarbeitung genauso hilfreich, wie
> das lernen von Japanisch wenn man Kisuaheli kann.

Voelliger Bloedsinn.

von Karl H. (kbuchegg)


Lesenswert?

Eine korrekte Klasse 'Daten' sieht so aus
1
class Daten
2
{
3
  public:
4
    Daten()
5
    : name( NULL )
6
    {}
7
8
    Daten( const Daten& arg )
9
    : name( NULL )
10
    {
11
      newname = new char[ strlen( s.name ) + 1 ];
12
      strcpy( name, s.name );
13
    }
14
15
    Daten & operator=( const Daten & s )
16
    {
17
      char * tmp = new char[ strlen(s.name) + 1 ];
18
      strcpy( tmp, s.name );
19
      delete [] name;
20
      name = tmp;
21
      return *this;
22
    }
23
24
    ~Daten()
25
    {
26
      delete [] name;
27
    }
28
29
    void setNEWname (const char *c = "")
30
    {
31
      char * tmp = new char[ strlen(c) + 1 ];
32
      strcpy( tmp, c );
33
      delete [] name;
34
      name = tmp;
35
    }
36
37
38
private:
39
   char * name;
40
};

Und jetzt vergleich das mal mit einer "richtigen" C++ Lösung, so wie sie 
eigentlich sein sollte:
1
#include <string>
2
class Daten
3
{
4
  public:
5
    void setNEWname (const char *c = "")
6
    {
7
      name = c;
8
    }
9
10
11
private:
12
   std::string name;
13
};

von Karl H. (kbuchegg)


Lesenswert?

Peter Stegemann schrieb:
>
> Doch, sehr wohl. Denn hier geht's kaum um wirklich spezielles
> String-Wissen, sondern um einfache Set- und Get-Methoden, mit ein
> bisschen allokieren und kopieren. Da auf std::string zu verweisen ist
> kontraproduktiv.

Dann sollte man sich auch auf Setter und Getter konzentrieren und nicht 
auf ds Verwalten von dynamischen Resourcen.

>> In C++ gibt es eine offizielle String Klasse die genauso vorhanden ist,
>> wie eine Dateibehandlung. Mit der sollte man erst mal anfangen, ehe man
>> sich selber auf das Niveau der eigenen String Allokierung begibt.
>
> Beides ist nicht immer vorhanden und auch oft nicht optimal.

Wenn wir in Mikrovontroller & Elektronik wären würde ich dir recht 
geben. ABer wir sind hier in PC-Programmierung. Und da gibt es nun mal 
in C++ eine String Klasse.
Und selbst wenn es diese nicht gibt, dann hat in einer Firma schon 
jemand eine geschrieben.

> Gerade
> Dateibehandlung ist in der STL einfach nur noch schraeg, voellig
> unnoetig abstrahiert. Mit ordentlichen File- und Directory-Klassen waere
> der C++-Welt mehr gedient gewesen.

Geb ich dir recht.
Trotzdem hält der Vergleich:
Wenn du in C an ein File rannwillst, implementierst du auch kein halbes 
Dateisystem mit dynamischer Handle-Allokierung und Bufferung. Genauso 
wie du ein fopen, fwrite, fread zur Verfügung hast, hast du in C++ ein 
std::string zur Verfügung.

> Nur weil es fuer C++ std::string gibt, heisst das nicht, dass das
> vernuenftige Strings sind.

Doch.
Die sind vernünftig. Zumindest in dem Sinne, dass sie funktionieren, was 
man von grob geschätzt 70% aller 'Ich implementier mir meine C-Strings 
in C++ selber'-Klassen nicht sagen kann.

> Das tun sie auch nicht immer. Aber das merkt man erst im harten
> Praxisalltag, nicht im Elfenbeinturm.

Dann ist das ein Fehler in der jeweiligen STL. Den teilt man dem 
Hersteller mit, der fixt den Bug und alle sind glücklich.

Und mal ehrlich: Ich hab zwar auch schon einige Probleme in der STL 
gesehen, aber eine String Klasse hat noch immer funktioniert.

> Wo soll denn die Erfahrung herkommen, wenn schon die Stringverarbeitung
> umschifft wird? Strings sind sehr praktisch, um die Tuecken von new,
> delete, Resourcenverwaltung und Pointern zu lernen.

Ja.
Aber da geht es um das erlernen, wie man mit dynamischen Resourcen 
umgeht. Die meisten lernen diesen ganzen Kram allerdings zu einem 
Zeitpunkt an dem eigentlich 'Stringverarbeitung' ansteht. Und dazu 
braucht es keine dynamische Allokierung im Eigenbau.

> Quatsch ist, erst mal C++ in der Softvariante zu lehren, dem Schueler zu
> vermitteln wie einfach es ist ein dickes Programm zu schreiben

Sorry, Aber das seh ich ganz anders.
Denn das dicke Programm wird plötzlich ganz schlank, wenn er die Dinge 
mit STL Mitteln angeht.

(Warst nicht du es, der in einem anderen Thread eine Filebearbeitung in 
C dynamisch ausformuliert hat. Dort sieht man doch am allerbesten was 
einem der Einsatz der C++ Klassen bringt. Eine Handvoll C++ Zeilen 
kontra 2 Seiten C-Code. Was davon nist jetzt dicker und 
fehleranfälliger)

> Voelliger Bloedsinn.

Tut mir leid.
Das ist meine Meinung: Völliger Blödsinn ist es, einen Anfänger in 
C-Stringverarbeitung hineinzujagen, wenn er mit std::string seine Dinge 
mehr als ausreichend geregelt bekommt.

von Tim (Gast)


Lesenswert?

@  Karl heinz Buchegger

für was verwendest du hier den Adressoperator das geht doch ohne auch

Daten Hierrr!!!!! operator=( const Daten & s )
    {
      char * tmp = new char[ strlen(s.name) + 1 ];
      strcpy( tmp, s.name );
      delete [] name;
      name = tmp;
      return *this;
    }

von Karl H. (kbuchegg)


Lesenswert?

@Peter

Nicht falsch verstehen. Ich propagier keineswegs, dass ein C++ 
Programmierer nicht mit dynamischen Resourcen umgehen können muss.

Keineswegs.

Ich bin nur dafür, dass dieses Thema zu geeigneter Zeit gemacht wird und 
nicht wenn der Lernende mit hunderttausend andere Dingen überflutet 
wird, die er erst einmal einordnen muss.

von Karl H. (kbuchegg)


Lesenswert?

Tim schrieb:
> @  Karl heinz Buchegger
>
> für was verwendest du hier den Adressoperator das geht doch ohne auch

Wenn du haben willst, das das Objekt an welches du gerade zugewiesen 
wurde beim return noch einmal kopiert wird, dann mach das ruhig! Stell 
aber besser sicher, dass der Copy Construktor richtig funktioniert und 
vor allen Dingen nicht durch Aufruf des Zuweisungsoperators definiert 
wurde. Ansonsten gibts nämlich eine Endlosschleife :-)

Ist eine Kopie zuviel, aber was solls. Rechner sind ja schnell genug 
heutzutage.

> Daten Hierrr!!!!! operator=( const Daten & s )

Dieser 'Adressoperator' ist eine Referenz!

von Tim (Gast)


Lesenswert?

in deinem Code brauchst du auch noch diesen Konstruktor

Daten(const char *c) : name( NULL )
    {
      char * tmp = new char[ strlen(c) + 1 ];
      strcpy( tmp, c );
      delete [] name;
      name = tmp;
    }

damit diese aufufe möglich sind

Daten name("Karl");

von Tim (Gast)


Lesenswert?

friend ostream &operator<<(ostream &os, const Complex &z)
{
   return os << blablabla;
}

aber hier wird doch das & vor dem Operator benötigt benötigt
wieso ist das dann da so

von Karl H. (kbuchegg)


Lesenswert?

Tim schrieb:
> friend ostream &operator<<(ostream &os, const Complex &z)
> {
>    return os << blablabla;
> }
>
> aber hier wird doch das & vor dem Operator benötigt benötigt
> wieso ist das dann da so

An dieser Stelle kann es keinen Adressof-Operator geben.
Im Funktionskopf ist & immer das Kennzeichen einer Referenz.

os wird per Referenz übergeben
z wird per Referenz übergeben
die Funktion liefert eine Referenz

Einen Adressof-Operator kannst du immer nur im Funktionsrumpf haben oder 
in Initialisierungen. Grob gesprochen: in Code der auch ausgeführt wird.
Ein Funktionskopf führt aber nichts aus. Er deklariert nur, wie die 
Schnittstelle zum Aufrufer aussieht.

von Tim (Gast)


Lesenswert?

hab ich jetzt nicht verstanden! was ist da der Unterschied zwischen

friend ostream &operator<<(ostream &os, const Complex &z)


Daten  operator=( const Daten & s )


Daten & operator=( const Daten & s )

von Karl H. (kbuchegg)


Lesenswert?

Tim schrieb:
> hab ich jetzt nicht verstanden! was ist da der Unterschied zwischen
>
> Daten  operator=( const Daten & s )

Hier wird ein Daten OBJEKT zurückgegeben.
Damit dies möglich ist, muss das Objekt aus der Funktion herauskopiert 
werden. Je nach Objekt, kann es aber teuer sein ein Objekt zu kopieren.

> Daten & operator=( const Daten & s )

Hier wird eine REFERENZ auf ein Datenobjekt zurückgegeben.
Eine Referenz ist nicht das Objekt selber, sondern sie steht für das 
Objekt. Damit man eine Referenz aus einer Funktion herauskopieren kann, 
muss nur sichergestellt sein, dass das eigentliche Objekt nach dem 
Funktionsaufruf noch existiert. Bei *this sollte das eigentlich ausser 
Frage stehen :-)
Gibt man eine Referenz aus der Funktion heraus, muss das Objekt nicht 
kopiert werden. Es muss nur nach dem Aufruf noch existieren.


Ich empfehle ein C++ Buch.

von Tim (Gast)


Lesenswert?

Bei Büchern dauert es zu lange bis man da die passende Antwort findet

ich hab sogar 2 Bücher

von Karl H. (kbuchegg)


Lesenswert?

Tim schrieb:
> Bei Büchern dauert es zu lange bis man da die passende Antwort findet
>

Klar. Wenn du erst zu lesen anfängst, wenn du auf ein Problem stößt.

Solche Bücher kann man auch im Vorfeld lesen. Sollte man sogar tun. Dann 
weiß man auch, was es so alles gibt. Wie das alles zusmmenhängt und in 
welchem Kapitel welches Thema behandelt wird. Und nein: Referenzen sind 
alles andere als ein esoterisches Thema, welches im Vorbeigehen auf den 
Fussnoten 2er Seiten abgehandelt wird.

> ich hab sogar 2 Bücher

Ach. Und? Beide schon ausgemalt?
(Sorry. Konnte nicht widerstehen)

von Tim (Gast)


Lesenswert?

wenn ich dir mein skript geb dann würdest du sehen das da sehr schnell 
über
Referenzen hinweggegangen wurde dort sind einige beispiele drinnen
und das wars

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Du weißt aber schon, daß es neben "Deinem Skript" auch andere Bücher 
gibt? Und daß Du für Dein Studium/Deine Ausbildung/Deine Schule auch 
Deinen Arsch notfalls in eine Bücherei bewegen solltest, um Dir 
Grundlagenwissen anzueignen?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.