Frage

Ich verstehe, dass die Funktion nicht erlaubt ist, den Zustand des Objekts zu ändern, aber ich dachte, dass ich irgendwo gelesen, dass der Compiler durfte davon ausgehen, dass, wenn die Funktion mit den gleichen Argumenten aufgerufen wurde, würde es den gleichen Wert zurückgeben und so könnte einen im Cache gespeicherte Wert wieder verwenden, wenn es verfügbar ist. z.

class object
{
    int get_value(int n) const
    {
        ...
    }

...


object x;

int a = x.get_value(1);
    ...
int b = x.get_value(1);

dann könnte der Compiler den zweiten Anruf entfernt optimieren und entweder den Wert in einem Register verwenden oder einfach tun b = a;

Ist das wahr?

War es hilfreich?

Lösung

const ist über Programmsemantik und nicht um Implementierungsdetails. Sie sollten eine Memberfunktion const markieren, wenn es, nicht den sichtbaren Zustand des Objekts ändern und sollte auf ein Objekt aufrufbar sein, der sich const ist. Innerhalb einer const Memberfunktion auf einer Klasse X, die Art der this ist X const *: Zeiger auf konstantes X Objekt. Somit werden alle Membervariablen innerhalb dieser Member-Funktion (außer const sind) effektiv mutable. Wenn Sie ein const Objekt haben, können Sie nur const Mitgliederfunktionen auf es nennen.

Sie können mutable verwenden, um anzuzeigen, dass ein Mitglied Variable innerhalb einer const Member-Funktion auch ändern kann. Dies wird normalerweise verwendet, um Variablen für die Caching Ergebnisse zur Identifizierung oder für Variablen, die den tatsächlichen beobachtbaren Zustand beeinflussen nicht wie Mutexe (Sie immer noch die Mutex in den const Elementfunktionen sperren müssen) oder Zähler verwenden.

class X
{
    int data;
    mutable boost::mutex m;
public:
    void set_data(int i)
    {
        boost::lock_guard<boost::mutex> lk(m);
        data=i;
    }
    int get_data() const // we want to be able to get the data on a const object
    {
        boost::lock_guard<boost::mutex> lk(m); // this requires m to be non-const
        return data;
    }
};

Wenn Sie die Daten durch Zeiger nicht direkt halten (einschließlich intelligenten Zeiger wie std::auto_ptr oder boost::shared_ptr), dann wird der Zeiger const in einer const Member-Funktion, aber nicht die spitzen-to-Daten, so dass Sie das spitze ändern Daten.

Wie für das Caching: im Allgemeinen kann der Compiler dies nicht tun, weil der Staat zwischen den Anrufen ändern könnte (vor allem in meinem Multi-Threaded-Beispiel mit dem Mutex). Wenn jedoch die Definition inline ist, dann kann der Compiler den Code in die aufrufende Funktion ziehen und optimieren, was es dort zu sehen. Dies könnte in der Funktion führen effektiv nur einmal aufgerufen werden.

Die nächste Version des C ++ Standard (C ++ 0x) haben ein neues Schlüsselwort constexpr. Funktionen getaggt constexpr einen konstanten Wert zurück, so können die Ergebnisse zwischengespeichert werden. Es gibt Grenzen, was Sie in einer solchen Funktion (in der Reihenfolge, dass der Compiler diese Tatsache überprüfen kann) tun können.

Andere Tipps

Das Schlüsselwort wandelbar auf Membervariablen ermöglicht const Funktionen, die den Zustand des Objekts in der Hand zu verändern.

Und nein, es funktioniert nicht Cache-Daten (zumindest nicht alle Anrufe), da der folgende Code eine gültige konstante Funktion ist, die im Laufe der Zeit ändert:

int something() const { return m_pSomeObject->NextValue(); }

Beachten Sie, dass der Zeiger const sein kann, wenn die anvisierten Objekts ist nicht const, also der Aufruf von Nextvalue auf Someobject kann oder auch nicht ändern, es eigenen internen Zustand. Dies bewirkt, dass die Funktion etwas unterschiedlichen Werten jedes Mal zurück es aufgerufen wird.

Allerdings kann ich nicht beantworten, wie der Compiler mit const Methoden arbeitet. Ich habe gehört, dass es bestimmte Dinge optimieren kann, obwohl ich es aussehen müsste bis sicher sein.

Nein.

Eine const-Methode ist eine Methode, die nicht den Zustand des Objekts ändern (das heißt seine Felder), aber man kann das nicht annimmt gegeben wird, um den gleichen Eingang, Rückgabewert einer const-Methode bestimmt. Mit anderen Worten bedeutet nicht const Schlüsselwort, dass die Funktion eine Eins-zu-eins. Zum Beispiel einer Methode, die die aktuelle Zeit zurückgibt, ist eine konstante Methode aber der Rückgabewert Änderungen zwischen den Anrufen.

Das Schlüsselwort const auf eine Member-Funktion markiert die diese Parameter als konstant. Die Funktion kann immer noch stumm globale Daten (so kann nicht zwischengespeichert werden), nicht aber Daten Objekt (so dass für Anrufe auf const-Objekten).

In diesem Zusammenhang ist eine const Member-Funktion bedeutet, dass this auch als const Zeiger behandelt wird. In der Praxis bedeutet es Ihnen nicht den Zustand der this innerhalb einer const Elementfunktion zu ändern erlaubt.

Für no-Nebeneffekt Funktionen (dh, was Sie versuchen zu erreichen), GCC hat eine "Funktion Attribut" genannt pure (Sie es verwenden, um __attribute__((pure)) sagen): http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html

Ich bezweifle es, könnte die Funktion noch eine globale Funktion aufrufen, die den Zustand der Welt verändert und nicht verletzen konst.

Hinzu kommt die Tatsache, dass die Member-Funktion globale Daten ändern können, ist es möglich, dass die Member-Funktion zu ändern erklärt ausdrücklich wandelbar Mitglieder des Objekts in Frage.

Corey ist richtig, aber bedenken Sie, dass alle Mitgliedsvariablen, die als markiert sind wandelbar können in const Member-Funktionen geändert werden.

Es bedeutet auch, dass diese Funktionen von anderen const Funktionen aufgerufen werden können, oder über andere const Referenzen.


Edit: Verdammt, von 9 Sekunden geschlagen .... 9 !!! :)

const Methoden werden auch statische Einheimischen ändern erlaubt. Zum Beispiel (versperren und wiederholten Anrufen () werden steigende Werte zurück - nicht im Cache gespeichert 0) die folgenden ist vollkommen legal:

class Foo
{
public:
    int bar() const
    {
        static int x = 0;
        return x++;
    }
};
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top