Ändern von self innerhalb der const-Methode über einen nicht const-Zeiger auf self

StackOverflow https://stackoverflow.com//questions/22053806

  •  21-12-2019
  •  | 
  •  

Frage

Im folgenden Beispiel const Das Objekt kann sich über ändern const Methode, weil es in dieser Methode über auf sich selbst zugreift non-const Zeiger.(Gleiches Programm auf ideone)

#include <iostream>

struct Object;

Object * g_pObject;

struct Object
{
    Object():m_a(0){}

    void ModifySelfViaConstMethod() const
    {
        g_pObject->m_a = 37;
    }

    int m_a;
};

int main()
{
    Object o;
    g_pObject = &o;

    const Object & co = o;
    std::cout << co.m_a << "\n";
    co.ModifySelfViaConstMethod();
    std::cout << co.m_a << "\n";

    return 0;
}

Ich bin nicht so gut darin, den C++-Standard zu lesen, also frage ich hier:

Was sagt der Standard dazu?

A)const Die Methode garantiert Ihnen nicht, dass Ihr Objekt unverändert bleibt, wenn Sie solche Dinge tun

b) Ist das klar definiert und muss es kompiliert werden?

c) andere?

War es hilfreich?

Lösung

Was sagt der Standard dazu?

Das heißt es (paraphrasierend). this Typ hat const Object *, sodass Sie Member nicht direkt ändern oder nicht konstante Memberfunktionen über aufrufen können this.Es sagt nichts darüber aus, was Sie mit globalen Variablen tun können, auf die die Funktion möglicherweise Zugriff hat.Es steuert nur den direkten Zugriff auf das Objekt, für das die Funktion aufgerufen wird.

const Die Methode garantiert Ihnen nicht, dass Ihr Objekt unverändert bleibt, wenn Sie solche Dinge tun

Nein, tut es nicht.Es gibt die Absicht an, dass die Funktion das Objekt nicht ändern wird, und bietet einen gewissen Schutz vor einem versehentlichen Verstoß gegen diese Absicht.Es hindert einen entsprechend geistesgestörten Programmierer nicht daran, es zu verwenden const_cast, oder (wie hier) unkontrollierte Kopplung über globale Variablen, um das Versprechen zu brechen.

Ist das klar definiert und muss es kompiliert werden?

Ja. o ist selbst nicht konstant, daher hindert Sie nichts daran, einen nicht konstanten Zeiger oder Verweis darauf zu verwenden.Der const Die Memberfunktion schränkt den Zugriff auf das Objekt nur über ein this, nicht auf beliebige Objekte über andere Zeiger.

Andere Tipps

Wenn Sie a const Funktion, es ist „zu Ihrem eigenen Besten“.

Mit anderen Worten: Sie erklären es const denn gemäß Ihrem ursprünglichen Entwurf soll es kein Objekt ändern, mit dem es während der Laufzeit aufgerufen wird.

Wenn Sie zu einem späteren Zeitpunkt in der Implementierung dieser Funktion das Objekt ändern, wird der Compiler Sie „anschreien“ und Ihnen sagen, dass es falsch ist.

Natürlich kann der Compiler einen solchen Versuch nur dann erkennen, wenn er angewendet wird this.

Im gegebenen Beispiel kann der Compiler das Problem nicht identifizieren, da ein Vergleich zwischen diesen erforderlich ist this Und g_pObject, und ein solcher Vergleich kann nur zur Laufzeit stattfinden.

Wenn eine Methode als deklariert wird const, stellt der Compiler sicher, dass die Instanz, auf die der zeigt this Der Zeiger wird nicht geändert.Wenn Sie versuchen, die zu ändern this Beispielsweise schlägt der Compiler fehl.Der Compiler hat jedoch keine Möglichkeit, dies zu wissen g_pObject Und this zeigen tatsächlich auf dieselbe Instanz.Das erfordert einen Laufzeitvergleich, und kein Compiler wird Zeit damit verschwenden, Laufzeitvergleiche aller innerhalb von a verwendeten Zeiger durchzuführen const Methode in dem unwahrscheinlichen Fall, dass sie könnte verbinde die this Zeiger.Wenn Sie also eine ändern möchten Object Über einen externen Zeiger müssen Sie Ihre eigene Prüfung durchführen, z. B.:

void ModifySelfViaConstMethod() const
{
    if (g_pObject != this)
        g_pObject->m_a = 37;
}

Konstanz ist in C++ ein Sicherheitsinstrument, keine Sicherheit.

Der Code, in dem die Konstanz berücksichtigt wird, wird höchstwahrscheinlich wie erwartet funktionieren, und alle unbeabsichtigten Versuche, die Konstanz aufzugeben, werden vom Compiler gewarnt.

In Fällen, in denen „ich weiß, was ich tue“, findet man die ganze Vielfalt an Werkzeugen von const_cast Betreiber und mutable Schlüsselwort zur banalen C-Stilbesetzung.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top