verwenden von pointern ohne new?
-
Variablen in C++ haben immer Typen (sind also Objekte).
grrr schrieb:
double i = 5; double* p = &i; sizeof(i); //Ist '8' sizeof(p); //Ist '4' sizeof(*p); //Ist '8', ist ja 'i'
Was beweist das ?
-
wo liegt da der unterschied:
void DisplayName(Worker const &worker) { std::cout << worker.getName() << std::endl; } void DisplayName(const Worker &worker) { std::cout << worker.getName() << std::endl; }
bye
-
@mike.: gibt keinen
Old School Coder schrieb:
Das ist OK so. Referenzen haben dabei keinen Vorteil. Es sind sowieso getürkte Pointer.
Das ist doch totaler käse, was du da erzählst. Referenzen haben riesige vorteile:
void OldSchoolDisplayName (Worker* worker) { cout << worker->getName() << endl; } void newSchoolDisplayName (Worker const & worker) { cout << worker.getName() << endl; } int main() { { // new school newSchoolDisplayName (Worker ("Hans", "Wutscht")); } { // old school Worker worker("Hans","Wurscht"); OldSchoolDisplayName (&worker); } }
In diesem minnibeispiel ist es nicht besonders ersichtlich, aber es gibt einige Fälle, wo das benannte anlegen solcher Wegwerf-Objekte den Code deutlich unübersichtlicher macht.
Vor allem, wenn die Argumente des Worker-Konstruktor nicht als std::string const &, sondern als std::string * definiert wären:
int main() { std::string vorname = "Hans"; std::string nachname = "Wurscht"; Worker worker(&vorname, &nachname); OldSchoolDisplayName (&worker); }
Sowas kann sich dann ganz schnell in ein Codewust steigern.
-
Helium schrieb:
Old School Coder schrieb:
Das ist OK so. Referenzen haben dabei keinen Vorteil. Es sind sowieso getürkte Pointer.
Das ist doch totaler käse, was du da erzählst. Referenzen haben riesige vorteile:
void OldSchoolDisplayName (Worker* worker) { cout << worker->getName() << endl; } void newSchoolDisplayName (Worker const & worker) { cout << worker.getName() << endl; } int main() { { // new school newSchoolDisplayName (Worker ("Hans", "Wutscht")); } { // old school Worker worker("Hans","Wurscht"); OldSchoolDisplayName (&worker); } }
void oldSchoolDisplayName (Worker* worker) { cout << worker->getName() << endl; } void newSchoolDisplayName (Worker const & worker) { cout << worker.getName() << endl; } int main() { newSchoolDisplayName (Worker ("Hans", "Wutscht")); oldSchoolDisplayName (&Worker ("Hans", "Wutscht")); return (0); }
Helium schrieb:
Sowas kann sich dann ganz schnell in ein Codewust steigern.
Der einzige Unterschied ist dann aber das &, das du bei einem Zeigerparameter für die Abfrage der Adresse setzen mußt. Und ob man das als störend oder gar unübersichtlich empfindet, ist Geschmackssache.
Referenzen haben durchaus Vorteile. Was du genannt hast, fällt allerdings nicht darunter.Moritz
-
Naja, klappt nur solange keine Konvertierungen im Spiel sind.
void fooRef (std::string const & bar); void fooPtr (std::string const * bar); fooRef ("Hallo"); fooPtr (&std::string ("Hallo")); // hmm...
-
Chew-Z schrieb:
int& j = i; // j ist nur alias, es wird KEIN neues Objekt erstellt !! int* p = &i; // p ist ein neues Objekt das Speicher benötigt.
Also eine Referenz belegt bei mir auch 4 byte, wie ein Pointer. Versteh ich nicht, warum sie kein Objekt sein soll (wenn man denn die skalaren Typen als Objekte ansieht).
Zumal bei aelteren Compilern Referenzen ja noch über Pointer implementiert wurden (ich weiss allerdings nicht wirklich, wie das jetzt geloest wird, falls das denn nicht mehr so ist).Gruss,
DeSoVoDaMu
-
DeSoVoDaMu schrieb:
Zumal bei aelteren Compilern Referenzen ja noch über Pointer implementiert wurden (ich weiss allerdings nicht wirklich, wie das jetzt geloest wird, falls das denn nicht mehr so ist).
Das ist auch heute noch so, auch wenn es vom Standard nicht vorgeschrieben ist.
Moritz
-
DeSoVoDaMu schrieb:
Also eine Referenz belegt bei mir auch 4 byte, wie ein Pointer.
Wie kommst du darauf? Referenzen sind keine "greifbaren" Objekte, du kannst also auch keine Grösse davon ermitteln.
-
Glamdrink schrieb:
Was beweist das ?
Man sieht, das die Pointervariable p vier Bytes speicherplatz besetzt. Jede Pointervariable tut das, egal, auf was für einen Objekttyp sie zeigt. Deshalb verwende ich in meinem Beispiel den Typ double, weil der 8 und nicht wie int 4 Byte belegt. (auf jedenfall auf win32)
DeSoVoDaMu schrieb:
Also eine Referenz belegt bei mir auch 4 byte, wie ein Pointer
Wie kriegst du die grösse der referenz?
double i = 5; double &j = i; double &leer; cout << sizeof (i) << "\n"; //Gibt 8, da double cout << sizeof (j); //Gibt 8, da 'grösse des inhalts der var i' cout << sizeo[cpp]f (leer); //Das geht nicht. Da stirb der compiler.
das du auch 4 Bytes bekommst, liegt wohl daran, das es ne int war
-
double i = 5; double &j = i; double &leer; cout << sizeof (i) << "\n"; //Gibt 8, da double cout << sizeof (j); //Gibt 8, da 'grösse des inhalts der var i' cout << sizeof (leer); //Das geht nicht. Da stirb der compiler.
er wird wohl eher hier sterben:
double &leer;
abgesehen von ästhetischen und semantischen gesichtspunkten ist die wahl zwischen pointer und referenz auch eine optimierungsfrage. in allen gängigen implementierungen wird eine referenz intern durch pointer implementiert - aber zwingend nur dann wenn der compiler das referenzierte objekt, dort wo die referenz benutzt wird, nicht direkt sehen kann. falls also funktionen nicht inline expandiert werden oder - mitunter - wenn referenzen an temporaries gebunden werden. im übrigen zwingt die verwendung von pointern (und des addressoperators) objekte dazu, tatsächlich auch eine adresse zu haben. das ist bei register objekten aber nicht der fall, folglich können objekte die per pointer übergeben werden - theoretisch - nicht nur in registern existieren, was zweifellos ein nachteil ist. ein hoch optimierender compiler kann hier sicherlich z.T. abhilfe schaffen wenn es gelingt, den pointer zu eliminieren, aber prinzipiell ist das a)nicht immer möglich und b)teilweise sehr schwierig wegen aliasing problemen.