C++ Read only Methode

schwegennagel

Cadet 4th Year
Registriert
Feb. 2005
Beiträge
79
Hallo,
bin gerade etwas auf Hilfe angewiesen.
Ich frage mich was ist der Unterschied zwischen: methode(const &ref) { int wert; wert=ref;}
und
methode(const &ref) const { int wert; wert=ref;}

Das zweite wird ja als Read-only Methode bezeichnet. Aber was ist bein der zweiten Methode anders als bei der ersten? Bei beiden wird ja eine konstante Referenz übergeben, sodass man das Argument nicht mehr ändern kann.
 
AW: C++ Read only Methode

Bei der const Referenz die du deiner Methode übergibst kannst du wie schon gesagt keine Member-Variablen auf dieser Referenz ändern bzw. keine Methoden auf dieser Referenz aufrufen die eine Member-Variable dieser Referenz ändern würden.
Und genau hier greift das zweite const aus dem zweiten Fall: Wenn eine Methode als const deklariert (Keyword const hinter der Methode) dürfen innerhalb dieser Methode Member-Variablen nicht geändet werden, es wird also sichergestellt, dass eine Methode den Zustand eines Objektes nicht verändert.

Ausnahmen gibt es aber auch: Wenn eine Member-Variable als mutable deklariert wurde, so kann sie auch in einer const-Methode geändet werden.
 
Moin,
also bei der zweiten Methode kein Objekt und keine Member-Variable geändert werden. Bei der ersten Methode können nur die mit const bezeichneten Member-Variablen nicht geändert werden. Ist das so richtig? Wäre ganz nett, wenn mir jemand noch ein kleines Beispiel geben könnte- so ganz klar ist mir der Unterschied nicht.
 
Nun gut,
nehmen wir mal an wir haben eine Methode ich nenne sie einfach mal "doSomething()"

Einmal die Variante ohne const:
Code:
void someClass::doSomething(const bool& aBool)
{
      mBoolVar = aBool;
}

Alles kompiliert ohne Murren.

Jetzmal die Variante mit const:
Code:
void someClass::doSomething(const bool& aBool) const
{
      mBoolVar = aBool;  // <-- Hier gibts einen aua auf die finger vom compiler
}

Hier kompiliert er nicht mehr, denn das "const" verhindert das Klassenvariablen verändert werden.
Der Zweck dahinter ist die Vermeidung von Programmfehler, d.h. wenn man weiß das diese Methode keine Variablen verändern soll dann legt man sie als const fest.
Sollte im Laufe der Entwicklung jemand etwas daran ändern dann gibts wieder aua auf die Finger.
 
Noch ein anderes Beispiel:

PHP:
class A
{
	unsigned int x;
	mutable unsigned int y;
public:
	void foo()
	{
		x = y = 17;
	}

	void bar() const
	{
		x = 17;	// Fehler, const Methode darf keine non mutable Variablen ändern 
		y = 17;	// Kein Fehler, y ist mutable
	}
};

int main()
{
	A a;
	const A& ca = a;	// Konstante Referenz

	a.foo();	// Kein Fehler
	ca.foo();	// Fehler weil ca const ist, foo aber nicht

	a.bar();	// Kein Fehler
	ca.bar();	// Kein Fehler, sowohl ca als auch bar sind const	
}
 
Ja, danke ich habe es jetzt verstanden:D:D

Noch eine andere Frage zu folgendem Programmstück:
#include "Flaeche.h"
template <class T>
T expand(T p,const int& oldlen,const int& newlen)
{
//neuen Bereich allokieren
T pnew = (T)new void*[newlen];
//Umspeichern des bisherigen Bereiches
for (int i=0; i<oldlen; i++) pnew = p;
//Löschen des alten Bereiches
delete[] p;

return pnew;
}
...
...

class CFlaechenListe
{
private:
...

void append (CFlaeche* f)
{
if (alloclen < laenge+1)

pf = expand(pf, laenge, alloclen+=allocstep);
pf[laenge++] = f;
}


T pnew = (T)new void*[newlen]; das T vor pnew legt fest, dass pnew vom Datentyp T ist. Das (T) ist ein casting, sodass der Rückgabewert von new auch vom Typ T ist. Seh ich das richtig?
 
Das siehst du richtig. Allerdings ist der Code so furchtbar, dass du ihn am besten gleich wieder vergessen solltest.
 
Grundsätzlich kann man sagen das bei new nie gecastet wird. In diesem Fall benutzt man "new T".
 
Genau. Außerdem sind nur Pointer beim Aufruf sinnvoll, also sollte T* in der Signatur stehen. Zusätzlich werden void*-Arrays mit new erzeugt und T*-Arrays wieder zerstört. Auch wenn das für den Compiler wahrscheinlich einerlei ist, ist das undefiniertes Verhalten.

Dazu kommt das sehr wahrscheinlich lineare Wachsen des Arrays (miserable Performance einerseits, Schreddern des Heaps andererseits). Kleine, aber potente Fehler wie pf[laenge++] = f;, wo laenge sicherlich erst nach dem erfolgreichen Einfügen erhöht werden soll (auch wenn es in diesem einfachen Beispiel nicht fehlschlagen kann). Ich hätte noch ein paar Kleinigkeiten, aber das reicht wohl :D

Auch wenn das vielleicht just for fun oder zu Übung gebaut wurde, fährt man hier mit std::vector in jeder Hinsicht besser.
 
Zuletzt bearbeitet:
Zurück
Oben