[C++] Zeiger, Referenzen, Variablen

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
cypher
Beiträge: 6
Registriert: 09.05.2011, 20:16
Wohnort: Hannover
Kontaktdaten:

[C++] Zeiger, Referenzen, Variablen

Beitrag von cypher »

Guten Morgen Community,

erstmal möchte ich alle in diesem Forum begrüßen und hoffe wir können uns im Verlauf des Zeit gegenseitig helfen :) Dazu dient ja ein Forum.
Nun zu meiner Frage.

Ich arbeite und entwickle schon seit 3 Jahren im Bereich der Webprogrammierung. (PHP,MySQL,XHTML,CSS,Javascript,AJAX...). Mit den Begriffen Variablen und Referenzen kam ich im Bereich von PHP schon oft in Berührung.
Das Problem was ich zurzeit habe, ist das Verständnis aufzubauen, wann ich Variablen, Zeiger bzw Referenzen nutzen soll.
Wie diese jeweiligen Sachen funktionieren habe ich schon verinnerlicht, nur ich weiß nicht immer genau wann ich was nutzen sollte.

Ich würde mich über eine kleine Erläuterung sehr freuen.
Grüße,
cypher
Zuletzt geändert von Chromanoid am 10.05.2011, 11:25, insgesamt 1-mal geändert.
joggel

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von joggel »

Huhu und willkommen im Forum,

Joar, Zeiger und Referenzen sind im Prinzip dasselbe.
Diese nutzt man am bestem *immer* (in der Regel) wenn man eine Variable an eine Funktion übergeben soll, oder allgemein: Variablen "be- oder verarbeiten".
Der Sinn dahinter:
Zeiger bzw. Referenzen sind nur 4Byte groß (auf 32-Bit-Systemen).
Es wird also nur die Adresse der Variable an die Funktion übergeben, und alle Zugriffe aus der Funktion auf die Variable geschieht über diese Adresse.
Verwendet man dagegen bei der Übergabe an die Funktion keine Referenzen/Zeiger wird eine Kopie des zu übergebenden Objektes erstellt, und damit arbeitet dann die Funktion... manchmal soll das auch sinnvoll sein, aber eher selten.
Bei eben großen Objekten (bspw. Arrays oder so) wird alles kopiert... das führt zu Perfomranceeinbusen.
Da wo es schnell gehen soll, verwendet man dann dafür Referenzen oder Zeiger, was man eigentlich immer tun sollte imo.

Hoffe das hat Dir etwas Licht ins Dunkle gebracht.
cypher
Beiträge: 6
Registriert: 09.05.2011, 20:16
Wohnort: Hannover
Kontaktdaten:

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von cypher »

Hallo joggel,

danke dir für deine nette Antwort. Das mit dem Funktionen war mir so schon bewusst. Es macht auch Sinn einer Funktion die einen bestimmten Wert nur weiterverarbeitet, die Referenz zu übergeben anstatt eine Kopie davon anzufertigen. Danke dir für das nette Beispiel.

Aber wieso gibt es dann Referenzen und Zeiger? Welcher Programmierstil ist da der modernere? Was macht aus Performancegründen mehr Sinn (wenn es da überhaupt einen Unterschied gibt). Kann man nur Zeiger nutzen oder auch nur Referenzen?

Danke dir schonmal für deine Antwort.
Grüße,
cypher
joggel

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von joggel »

Referenzen sind eine Neuerung von C++ .
Vorher gab es nur Zeiger. Was im Prinzip dasselbe ist.
Aber wieso gibt es dann Referenzen und Zeiger?
Warum es nun nochmal explizit Referenzen gibt,... kA. ^^
Welcher Programmierstil ist da der modernere?
Man kann nicht immer Referenzen verwenden, Zeiger eigentlich schon.
Aber sowas hat sich eigentlich ganz gut durchgesetzt:

Code: Alles auswählen

void aFunction(const MyObject& anInstanceOfMyObject);
Was macht aus Performancegründen mehr Sinn (wenn es da überhaupt einen Unterschied gibt)
Ich glaube, dass das aus Performancesicht keinen Unterschied macht...
Kann man nur Zeiger nutzen oder auch nur Referenzen?
Man kann nicht immer Referenzen benutzen, Zeiger hingegen schon.

Gruß
joggel
Benutzeravatar
Schrompf
Moderator
Beiträge: 4879
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von Schrompf »

Ich würde grundsätzlich zu Referenzen raten, weil der Compiler da zusätzliche Mittel hat, um Dich auf Fehler in der Verwendung hinzuweisen. Man kommt allerdings nicht immer ohne Zeiger aus. Ich versuche mich mal in einer Faustregel:

Benutze immer Referenzen, außer:
a) du willst mit Speicheradressen rechnen
b) die verwiesenen Objekte wechseln den Besitzer
oder c) es ist bequemer, weil die in Frage kommenden Objekte eh alle mit new erzeugt werden.

c) ist seltener als gemeinhin gedacht. new kommt in modernem C++ relativ selten zum Einsatz. a) ist klar, ist aber extrem selten. Ein guter Grund ist b), z.B. sowas wie:

root->addWidget( new Label( "bla blubb"));

da wäre die Funktion z.B. ein "void addWidget(BaseWidget* widget)" sein, weil an dieser Stelle das Objekt den Besitzer wechselt.

Trotzdem gilt die allgemeine Empfehlung: benutze immer erstmal Referenzen, bis Du auf irgendwas Unpassendes oder Unbequemes stößt, was die Verwendung von Zeigern notwendig macht.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
cypher
Beiträge: 6
Registriert: 09.05.2011, 20:16
Wohnort: Hannover
Kontaktdaten:

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von cypher »

Hallo Schrompf, Hallo Joggel,

vielen dank an euch beiden. Gerade die Erklärung von Schrompf hat mir ein bisschen das Licht am dunklen Himmel erhellt. ;)
Gerade wenn man aus einer Programmiersprache (PHP) kommt, wo man sich im Normalfall nicht um eine Speicheraddressierung etc kümmern muss und Begriffe wie Datensegment, Heap bzw. Stack komplett nicht aufgetaucht sind, ist der Umstieg erstmal ein AHA-Effekt :)

Vielen Dank für die Aufklärung zu diesem Thema. Ich probiere jetzt das neue Wissen anzuwenden um es zu festigen.

Grüße,
cypher
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von Krishty »

Referenzen benutzt man, wenn man ein bestimmtes Objekt lokal referenzieren statt kopieren will.

Zeiger benutzt man
  • Wenn man zum Ausdruck bringt, dass eine Referenzierung nicht zwingend gültig sein muss; z.B. bei einem optionalen Parameter. (Weil Zeiger nullptr sein können, Referenzen hingegen immer auf ein tatsächliches Objekt zeigen müssen).
  • Wenn das Objekt, das man referenziert, während der Lebenszeit der Referenz ein anderes sein kann; z.B. bei einem Iterator über ein Array, der bei jeder Iteration ein anderes Objekt referenziert. (Weil Zeiger im Gegensatz zu Referenzen geändert werden können.)
  • Wenn man mehrere Objekte referenziert, z.B. ein Array. Dann zeigt man üblicherweise auf das erste und hinter das letzte.
Gruß, Ky
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
cypher
Beiträge: 6
Registriert: 09.05.2011, 20:16
Wohnort: Hannover
Kontaktdaten:

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von cypher »

Hallo Krishty,

also kann man auch sagen, dass wenn man einer Funktion ein Array übergibt eine Referenz keinen Sinn machen würde, da eine Referenz nur einmalig auf eine bestimmte Speicheradresse zeigen kann (z.B. auf das erste Element eines INT-Arrays) ?
Da aber bei Zeigern der Wert geändert werden kann, worauf der Zeiger zeigt kann man das Array mit Hilfe eines Zeigers durchlaufen...mit einer Referenz wäre dies aber nicht möglich?
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von Krishty »

Genau. Um das vollständig zu verstehen, solltest du dich aber in Zeigerarithmetik einarbeiten – dass ++ptr nicht auf das nächste Byte zeigt, sondern auf das nächste Objekt und sowas.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Schrompf
Moderator
Beiträge: 4879
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von Schrompf »

Das Ziel des Verweises kann jederzeit geändert oder auch als nicht änderbar markiert werden. Dazu gibt es "const". Aber ein Zeiger kann zur Laufzeit sein Ziel ändern, eine Referenz nicht. Wenn Du über ein Array iterieren willst, könntest Du einen Zeiger, aber keine Referenz nehmen, weil Du zum Iterieren den Zeiger von einem Element zum nächsten bewegen musst.

Komm übrigens gar nicht erst auf die Idee, Arrays manuell zu basteln. Dazu gibt es den std::vector und sein Iterator Interface. Und einen Vector kann man per Referenz auch prima rumreichen.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von Krishty »

Schrompf hat geschrieben:Komm übrigens gar nicht erst auf die Idee, Arrays manuell zu basteln. Dazu gibt es den std::vector und sein Iterator Interface.
… und das ist? Ein Zeiger. Zeiger und Iteratoren werden exakt gleich angewandt; nur das eine ist verpöhnt und das andere nicht.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Schrompf
Moderator
Beiträge: 4879
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von Schrompf »

Nein. Ein std::vector ist ein Container, also ein Zeiger mit Größe und Kontextinfo, verpackt in eine halbwegs durchdachte und gut getestete Klasse, mit Exception-Garantien soweit möglich und vor allem einer zuverlässigen Benutzbarkeit mit einfachem Interface. Und es lässt sich schlicht per Reference oder auch per Value rumreichen. Wenn Du stattdessen ein new[] oder old-style Array[] benutzen willst, ist das auch ok. *Du* weißt, was Du tust. Der OP noch nicht.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von Krishty »

Missverständnis; ich habe nie was gegen ::std::vector gesagt. Ich sage, dass es für den OP jottwiedeh ist, ob er lernt, Daten durch Zeiger zu iterieren oder durch Iteratoren, weil sie das gleiche sind. Und vor allem, dass die Existenz von ::std::vector kein Grund ist, sich nicht mit Zeigern auseinanderzusetzen (sondern es sogar unter Alias erzwingt. Das zu wissen ist ziemlich wichtig; und die letzten Fragen die genau aus Unkenntnis dieser Tatsache herrühren sind hier noch nicht lange her). Ich habe ihn nie dazu angestiftet, new-Array rumzuschieben.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Schrompf
Moderator
Beiträge: 4879
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von Schrompf »

Ok, dann habe ich Dich missverstanden. Ich habe halt meinen eigenen Satz Erwartungen, was für Fehler ein C++-Neuling machen will, und passe schon vorab meine Ermahnungen an diese Erwartungshaltung an :-)
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
cypher
Beiträge: 6
Registriert: 09.05.2011, 20:16
Wohnort: Hannover
Kontaktdaten:

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von cypher »

Ich danke euch für eure Mühen und Zeit :)
C++ bzw. höhere Programmiersprachen, die dazu sogar noch streng typisiert sind, sind schon eine andere Welt :)

Grüße,
cypher
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4262
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von Chromanoid »

Naja ich würde PHP eher mit den höheren Programmiersprachen zusammenpacken ;)
cypher
Beiträge: 6
Registriert: 09.05.2011, 20:16
Wohnort: Hannover
Kontaktdaten:

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von cypher »

Ja gut, eigentlich hast du ja recht ^^ - PHP ist ja kein Maschinencode.
Ich habe dazu wohl das falsche Wort gewählt :)
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4262
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von Chromanoid »

Und PHP abstrahiert auch wesentlich mehr vom eigentlichen Rechner als C++... Naja sorry fürs offtopic :)
Benutzeravatar
Sternmull
Establishment
Beiträge: 264
Registriert: 27.04.2007, 00:30
Echter Name: Til
Wohnort: Dresden

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von Sternmull »

Ich seh das mit der Verwendung von Referenzen und Zeigern genau umgekeht: Man sollte Werte immer by-value Übergeben, es sei denn man hat einen realen Grund es nicht zu tun.

Auf diese Weise hält man sich nach Möglichkeit unerwartete Seiteneffekte vom Hals die entstehen wenn irgendwo ein Objekt modifiziert das auch an einer anderen Stelle referenziert wird an die man garnicht gedacht hat.

Moderne String-Klassen arbeiten mit "copy on write", d.h. eine Kopie des Objektes ist erst mal nicht viel mehr als eine Referenz auf das Original (und mehr oder weniger genau so effizient). Sobald der String aber modifiziert wird während er an anderer Stelle "referenziert" wird, erstellt er selbständig eine Kopie um die anderen "Kopien" nicht zu verändern. Das ist für den Nutzer der Stringklasse transparent: Die String-Instanzen verhalten sich genau so als würden sie bei jeder Zuweisen kopiert werden, tun es aber nur wenn es wirklich nötig wird und sind dadurch normalerweise recht effizient.

Deshalb sehe ich das ungefähr so: Alles was leichtgewichtig ist (Primitive wie int, float, double, kleine Strukturen etc.) immer per Kopie herum reichen wenn es möglich ist. Gleiches gilt für alle Typen die "copy on write" implementieren.

Bei der Entscheidung zwischen Referenz und Zeigern bin ich aber einer Meinung mit euch. Anzumerken wäre vielleicht noch das man Instanzen von Klassen mit virtuellen Funktionen grundsätzlich per Zeiger oder Referenz verwalten sollte.
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von Krishty »

Sternmull hat geschrieben:Auf diese Weise hält man sich nach Möglichkeit unerwartete Seiteneffekte vom Hals die entstehen wenn irgendwo ein Objekt modifiziert das auch an einer anderen Stelle referenziert wird an die man garnicht gedacht hat.
Das verstehe ich nicht recht: Wenn man ein Objekt verändert, dann tut man das nicht ohne Grund. Wenn man nicht will, dass der Rest des Programms etwas von dieser Veränderung mitbekommt, dann verändert man es überhaupt nicht.
Sollte nicht eher der Programmteil, der darauf beruht, dass sich ein Objekt, das er referenziert, niemals ändert, die Kopie anlegen und nicht der, der die Änderung durchführt und deshalb auch damit umgehen kann? Ich blicke da absolut nicht durch.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Sternmull
Establishment
Beiträge: 264
Registriert: 27.04.2007, 00:30
Echter Name: Til
Wohnort: Dresden

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von Sternmull »

Selbst wenn man ein Objekt per const & übergibt, kann es an anderer Stelle immer noch modifiziert werden... mit entsprechenden Auswirkungen auf den Code der sich darauf verlässt das es tatsächlich konstant ist. Und dann hat man den Salat: Wenn eine Kopie keine relevanten Performance-Probleme gemacht hätte, hat man sich vollkommen grundlos einen schwer diagnostizierbaren Bug eingehandelt.

Lieber erst mal Code schreiben der so wenig Fehlerquellen wie möglich hat. Wenn sich rausstellt das der zu langsam ist, dann lassen sich die hauptverantortlichen Stellen normalerweise relativ schnell identifizeren. In dem Moment kann man dann überlegen wo sich zusätzliche Komplexität für bessere Performance lohnt.
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von Krishty »

Jaa, ich hatte das Missverständnis bemerkt und den Beitrag nach 20 s schon wieder gelöscht. Du hast ihn aber trotzdem noch ergattert :) Siehe neue Fassung oben.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Sternmull
Establishment
Beiträge: 264
Registriert: 27.04.2007, 00:30
Echter Name: Til
Wohnort: Dresden

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von Sternmull »

Nun zu deiner editierten Antwort :)
Krishty hat geschrieben:Das verstehe ich nicht recht: Wenn man ein Objekt verändert, dann tut man das nicht ohne Grund. Wenn man nicht will, dass der Rest des Programms etwas von dieser Veränderung mitbekommt, dann verändert man es überhaupt nicht.
Das stimmt schon. Allerdings passiert in komplexen Programmen immer irgend was an das man nicht gedacht hat. Vielleicht arbeitt ein Thread mit einer Konfiguration die bei der letzten Benutzereingabe erstellt wurde. Wenn der Nutzer zwischendurch was anderes eingibt, dann könnte der Thread zwischendurch eine neue Konfiguration untergeschoben bekommen mit der er nicht gerechnet hat... und für die er sich nicht initialisiert hat, vielleicht sind nun z.B. seine allozierten Arrays zu klein und er schreibt ins Nirvana, oder er liest greift auf die Konfiguration zu während sie grad aktualisiert wird und macht dann totalen Müll. Da finden sich sicherlich noch schönere und häufiger zutreffende Beispiele (sicherlich auch ohne Multithreading). Aber der Punkt ist: Wahrscheinlich hätte es keinen gejuckt wenn die Konfiguration per Kopie statt per const & übergeben worden wäre. Dann hätte der Thread seine Arbeit korrekt abgeschlossen.
Krishty hat geschrieben:Sollte nicht eher der Programmteil, der darauf beruht, dass sich ein Objekt, das er referenziert, niemals ändert, die Kopie anlegen und nicht der, der die Änderung durchführt und deshalb auch damit umgehen kann? Ich blicke da absolut nicht durch.
Ich glaub ich bin grad zu müde um den Satz komplett zu verinnerlichen. Aber würde man sich die Sache nicht einfacher machen wenn man an den Stellen statt der const & gleich eine Kopie übergibt?
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von Krishty »

Sternmull hat geschrieben:Vielleicht arbeitt ein Thread mit einer Konfiguration die bei der letzten Benutzereingabe erstellt wurde. Wenn der Nutzer zwischendurch was anderes eingibt, dann könnte der Thread zwischendurch eine neue Konfiguration untergeschoben bekommen mit der er nicht gerechnet hat... und für die er sich nicht initialisiert hat, vielleicht […]. Aber der Punkt ist: Wahrscheinlich hätte es keinen gejuckt wenn die Konfiguration per Kopie statt per const & übergeben worden wäre. Dann hätte der Thread seine Arbeit korrekt abgeschlossen.
Ja, dann wollen wir aufs Selbe hinaus – nämlich, zu kopieren, damit nicht jemand anders versehentlich meinen Programmteil kaputtmacht, wenn er das Objekt verändert, während ich es noch benutze. Ich hatte deinen Text genau andersrum gelesen – dass man kopieren soll, um nicht versehentlich andere Programmteile kaputtzumachen, wenn man ein Objekt verändert, was sie noch referenzieren.

Für diesen Zweck sieht C++ eigentlich den volatile-Qualifier vor, der const ebenbürtig ist. Jedes Objekt, dessen Zustand sich über einen Aufruf auch ohne Zutun des Aufgerufenen verändert, müsste eigentlich (ich weiß nicht, ob es im Standard vorgeschrieben ist) volatile deklariert werden und würde dann nur noch von Funktionen akzeptiert, die den entsprechenden Parameter volatile deklariert haben und damit anzeigen, dass sie auf fremde Wirkung während ihrer Ausführung eingestellt sind. Auf diese Art und Weise ergibt sich im Programm neben der const-Correctness die volatile-Correctness. (Ich muss aber eingestehen, dass ich die außer bei sporadischem Multithreading nie benutzt habe.)
Sternmull hat geschrieben:Ich glaub ich bin grad zu müde um den Satz komplett zu verinnerlichen.
Schachtelung ist doch toll :)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Sternmull
Establishment
Beiträge: 264
Registriert: 27.04.2007, 00:30
Echter Name: Til
Wohnort: Dresden

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von Sternmull »

Ich glaub wir reden gerade aneinander vorbei: Ja, volatile ist für den Fall in dem man eine Referenz auf ein Objekt übergibt das man wissentlich in anderem Code verändert. Ich wollte aber zum Ausdruck bringen das man vorzugsweise eine Kopie statt einer Referenz verwenden sollte wenn man ein Objekt übergeben will von dem der Empfänger nicht erwartet das es von anderer Stelle modifiziert wird während er damit arbeitet. Denn dann ist sichergestellt das der Empfänger (die aufgerufene Funktion) mit der Kopie arbeiten kann ohne das anderer Code versehentlich doch an dem Objekt rüttelt.
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von Krishty »

Sternmull hat geschrieben:Denn dann ist sichergestellt das der Empfänger (die aufgerufene Funktion) mit der Kopie arbeiten kann ohne das anderer Code versehentlich doch an dem Objekt rüttelt.
Und ich will genau andersrum sagen, dass man das von allem erwarten kann, was nicht volatile deklariert ist (und sich nicht mit Dingen überlappt, die die Funktion wissentlich selber modifiziert – aber Aliasing ist ja wieder ein Thema für sich), auch ohne Kopie.

Ich möchte nur nicht den Mund zu weit aufreißen, so lange ich nicht die Paragraphen finde, nach denen das Programm ill-formed ist, falls sich etwas nicht volatile deklariertes durch wen anders ändert.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von CodingCat »

Naja, const garantiert ja eben gerade dem Aufrufer, dass sein Objekt nicht verändert wird. Wenn sich der Code auf der anderen Seite dann nicht an diese Garantie hält, ist das ein Fehler dieses Codes. Deshalb jetzt in C++ mit wilder defensiver Kopiererei anzufangen halte ich für Unsinn, das tolle an C++ ist ja gerade, dass es dieses Sprachfeature gibt, welches die Garantie formulier- und prüfbar macht, und so eigentlich unnötige Kopien auf sichere Weise endlich überflüssig macht.
Moderne String-Klassen arbeiten mit "copy on write", d.h. eine Kopie des Objektes ist erst mal nicht viel mehr als eine Referenz auf das Original (und mehr oder weniger genau so effizient).
Soweit ich informiert bin, schwindet COW aufgrund der Schwierigkeiten im Zusammenhang mit multi-threaded Umgebungen. Ich meine sogar gelesen zu haben, dass der neue C++-Standard COW bei Strings nicht mehr zulässt.

Nachtrag:
http://www.justsoftwaresolutions.co.uk/cplusplus/cplusplus-standards-committee-mailing-october-2008.html hat geschrieben:This has been under discussion for a while, but was finally approved at the September meeting. The changes in this paper ensure that it is safe for two threads to access the same std::string object at the same time, provided they both perform only read operations. They also ensure that copying a string object and then modifying that copy is safe, even if another thread is accessing the original. This essentially disallows copy-on-write implementations since the benefits are now severely limited.
Und zur Verbreitung von COW:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2668.htm hat geschrieben: compiler | library | '98 | '03 | '0x
GNU | libstdc++ | yes | yes | no
Microsoft | Dinkumware | yes | no | no
Zuletzt geändert von CodingCat am 10.05.2011, 23:30, insgesamt 1-mal geändert.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Sternmull
Establishment
Beiträge: 264
Registriert: 27.04.2007, 00:30
Echter Name: Til
Wohnort: Dresden

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von Sternmull »

Ja, erwarten würde man das. Aber es gibt doch hin und wieder Situationen in denen sich das Programm wieder aller Erwartungen unvorhergesehen verhält und dann doch etwas verändert wird was von einem Codeabschnitt als konstant angenommen wird. Und dieses Risiko kann man verringern indem man Referenzen und Zeiger nur dann benutzt wenn man sie wirklich braucht, und nicht generell auch überall einsetzt wo man ebensogut mit Kopien leben könnte. Es geht mir darum unnötiges Potential für unbeabsichtige Seiteneffekte zu reduzieren, also Bugs vorzubeugen.
Benutzeravatar
Sternmull
Establishment
Beiträge: 264
Registriert: 27.04.2007, 00:30
Echter Name: Til
Wohnort: Dresden

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von Sternmull »

CodingCat hat geschrieben:Naja, const garantiert ja eben gerade dem Aufrufer, dass sein Objekt nicht verändert wird.
Aber der Aufrufende oder anderer Code der eine nicht-konstante Referenz auf das Objekt hat kann das Objekt vollkommen legal modifizieren während der Aufgerufene nicht damit rechnet das es verändert wird. Wenn die konstante Referenz z.B. als Member in einem langlebigen Objekt gespeichert wird das keine Änderungen an diesem Objekt erwartet, dann könnte später jemand kommen und es heimlich doch noch verändern. Wenn an dieser Stelle eine Kopie in Frage kommt, dann sollte man sie meiner Meinung nach verwenden.
Benutzeravatar
Krishty
Establishment
Beiträge: 8267
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Zeiger, Referenzen, Variablen

Beitrag von Krishty »

CodingCat hat geschrieben:Naja, const garantiert ja eben gerade dem Aufrufer, dass sein Objekt nicht verändert wird. Wenn sich der Code auf der anderen Seite dann nicht an diese Garantie hält, ist das ein Fehler dieses Codes.
Wir reden nicht von dem Fall, dass der Aufgerufene das Objekt verändert, sondern jemand anders, während der Aufrufer damit arbeitet.
Sternmull hat geschrieben:Ja, erwarten würde man das. Aber es gibt doch hin und wieder Situationen in denen sich das Programm wieder aller Erwartungen unvorhergesehen verhält und dann doch etwas verändert wird was von einem Codeabschnitt als konstant angenommen wird.
Nein. Dann ist das Programm fehlerhaft. Und das zu umschiffen indem man einfach eine Kopie anlegt, bevor man damit arbeitet, ist wie, Zugriffsverletzungen abzufangen weil plötzlich alle Arrays nur noch halb so groß sind wie sie sein sollten. Ich bin mir ziemlich sicher: Ist die Referenz nicht volatile deklariert (und überlappt nicht mit etwas, was ich persönlich bewusst verändere), darf es sich nicht ändern.
Das ganze hat auch nichts mit nicht-konstanten Referenzen zu tun, denn const sagt nur, dass man das Objekt nicht verändert darf. Ob es auch andere nicht verändern dürfen, entscheidet volatile:
  • type & – kann ausschließlich durch den Aufgerufenen (die Funktion) verändert werden
  • type const & – kann von niemandem verändert werden
  • type volatile & – kann vom vom Aufgerufenen (der Funktion) und sonstwem verändert werden
  • type const volatile & – kann ausschließlich von wem anders verändert werden
Zuletzt geändert von Krishty am 10.05.2011, 23:43, insgesamt 1-mal geändert.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Antworten