Seite 1 von 2

[C++] Zeiger, Referenzen, Variablen

Verfasst: 10.05.2011, 11:00
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

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

Verfasst: 10.05.2011, 11:24
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.

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

Verfasst: 10.05.2011, 11:27
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

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

Verfasst: 10.05.2011, 11:35
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

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

Verfasst: 10.05.2011, 11:46
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.

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

Verfasst: 10.05.2011, 11:52
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

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

Verfasst: 10.05.2011, 11:59
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

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

Verfasst: 10.05.2011, 12:06
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?

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

Verfasst: 10.05.2011, 12:10
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.

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

Verfasst: 10.05.2011, 12:12
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.

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

Verfasst: 10.05.2011, 12:16
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.

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

Verfasst: 10.05.2011, 12:26
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.

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

Verfasst: 10.05.2011, 12:30
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.

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

Verfasst: 10.05.2011, 12:41
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 :-)

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

Verfasst: 10.05.2011, 12:49
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

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

Verfasst: 10.05.2011, 13:11
von Chromanoid
Naja ich würde PHP eher mit den höheren Programmiersprachen zusammenpacken ;)

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

Verfasst: 10.05.2011, 13:19
von cypher
Ja gut, eigentlich hast du ja recht ^^ - PHP ist ja kein Maschinencode.
Ich habe dazu wohl das falsche Wort gewählt :)

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

Verfasst: 10.05.2011, 13:22
von Chromanoid
Und PHP abstrahiert auch wesentlich mehr vom eigentlichen Rechner als C++... Naja sorry fürs offtopic :)

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

Verfasst: 10.05.2011, 21:46
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.

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

Verfasst: 10.05.2011, 21:59
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.

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

Verfasst: 10.05.2011, 22:05
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.

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

Verfasst: 10.05.2011, 22:07
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.

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

Verfasst: 10.05.2011, 22:19
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?

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

Verfasst: 10.05.2011, 22:42
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 :)

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

Verfasst: 10.05.2011, 22:53
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.

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

Verfasst: 10.05.2011, 23:14
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.

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

Verfasst: 10.05.2011, 23:19
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

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

Verfasst: 10.05.2011, 23:28
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.

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

Verfasst: 10.05.2011, 23:37
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.

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

Verfasst: 10.05.2011, 23:42
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