Frage Warum setzt C ++ const auf Zeigerdaten nicht durch? [Duplikat]


Mögliche Duplikate:
Warum funktioniert das const-Qualifikationsmerkmal nicht an Zeiger-Membern auf const-Objekten? 

Betrachten Sie die folgende Klasse mit einem Zeigerelement int *a. Die Methode const constMod wird vom Compiler erlaubt, obwohl er die Zeigerdaten modifiziert. Warum macht der Compiler die Zeigerdaten im Kontext der Methode const nicht konstant? Ob a war nur ein int, wir durften es nicht in einer const-Methode modifizieren.

class ConstTest
{
    public:

    ConstTest(int *p): a(p) {}

    void constMod() const {
        ++(*a);
    }

    int *a;
};

Ich benutze g ++ unter Linux.


13
2018-05-10 05:21


Ursprung


Antworten:


Es ist nur ein Eigentumsproblem ... es gibt keine Möglichkeit, dass der Compiler wissen kann, ob das angedeutete Objekt ein logischer Teil des Objekts ist oder nicht, so dass der Programmierer solche Probleme überwachen muss. const Mitglieder dürfen Operationen mit Nebenwirkungen durchführen, solange sie ihren eigenen scheinbaren Wert nicht verändern. Es ist nicht wirklich anders als sie sagen zu lassen std::cout::operator<<() oder irgendeine andere nicht-const Funktion ....


4
2018-05-10 05:25



Innerhalb constMod(), die Erklärung von a wird behandelt als:

int *const a;

was bedeutet das Zeiger hat einen konstanten Wert, nicht was es ist verweist auf. Es klingt, als würden Sie erwarten, dass es wie folgt behandelt wird:

const int *a;

was ist anders.


13
2018-05-10 05:25



Der Zeiger selbst wird nicht verändert, nur die Daten zeigen. Auch wenn es sich vom menschlichen Standpunkt aus komisch anhört, wird aus Sicht des Compilers kein Mitglied der Klasse verändert.


7
2018-05-10 05:25



Was im obigen Fall const ist, ist der Zeiger selbst. Du darfst das nicht tun ++a;. Es hindert Sie jedoch nicht daran, die Daten zu ändern darauf hingewiesen werden.


0
2018-05-10 05:27



Ich glaube, weil Sie hier versuchen, den Wert zu ändern, auf den Datamember verweist. Wenn Sie versuchen, das Datenelement zu ändern, wäre dies ein Fehler.

Das heißt, Sie erhalten einen Fehler, wenn Sie auf etwas anderes hinweisen, anstatt den Wert zu ändern


0
2018-05-10 05:27



const Mit den Mitgliedsfunktionen können Sie die Mitglieder nicht ändern.

In Ihrem Beispiel haben Sie einen Zeiger, der auf ein int zeigt.

Und in der const Methode ändern Sie den Wert, auf den es gezeigt wird, aber nicht den Zeiger selbst.

Versuche zu geben, ++a, die den Zeigerwert tatsächlich ändert und in Ihrem nicht erlaubt wird const Methode.


0
2018-05-10 05:39



Erwägen

const T immutable_object0;
const T immutable_object1;
const T* mutable_view = ...a condition... ? &immutable_object0 : &immutable_object1;
// then later you reseat
mutable_view = ...another condition... ? &immutable_object0 : &immutable_object1;

oder

const int immutable_data[120]
const int* mutable_view = immutable_data;
for(const int* end = immutable_data + 120; mutable_view != end; ++mutable_view) {
  // can't modify *mutable_view
}

Das liegt daran, dass Zeiger nicht immer Eigentum besitzen. Unter bestimmten Umständen sind Zeiger Ansichten zu einem Objekt (erstes Beispiel) oder sind Iteratoren zu einem rohen Feld (zweites Beispiel). Für diese Fälle ist es nicht sinnvoll, die auf den Zeigern verfügbaren Operationen einzuschränken, nur weil die Daten, auf die verwiesen wird, unveränderlich sind (oder als unveränderlich angesehen werden).

Das erste Beispiel ist ein wenig künstlich, aber eine gültige Version davon ist, wenn Sie ein Zeigerelement verwenden, um die Objektverknüpfung zu implementieren, und Sie nicht den Ärger eines Referenzmitglieds haben wollen. Manchmal sind die spitzen Typen zufällig const.


0
2018-05-10 05:50