webentwicklung-frage-antwort-db.com.de

Warum kann eine konstante Elementfunktion ein statisches Datenelement ändern?

Im Folgenden C++ Programm, das ein statisches Datenelement von einer const Funktion modifiziert, funktioniert einwandfrei:

class A 
{
  public:   
    static int a; // static data member

    void set() const
    {
        a = 10;
    }
};

Das Ändern eines nicht statischen Datenelements aus einer const -Funktion funktioniert jedoch nicht:

class A 
{
  public:   
    int a; // non-static data member

    void set() const
    {
        a = 10;
    }
};

Warum kann eine const Elementfunktion ein static Datenelement ändern?

81
msc

Es ist die Regel, das ist alles. Und das aus gutem Grund.

Das Qualifikationsmerkmal const für eine Memberfunktion bedeutet, dass Sie keine Membervariablen ändern können, die nicht der Klasse mutable und nicht der Klasse static entsprechen.

Aus Gründen der Rationalisierung ist der Zeiger this in einer const -qualifizierten Elementfunktion ein const-Typ, und this ist inhärent mit einem - verwandt. Instanz einer Klasse. static -Mitglieder sind keiner Klasseninstanz zugeordnet. Sie benötigen keine Instanz, um ein static -Mitglied zu ändern: Sie können dies in Ihrem Fall tun, indem Sie A::a = 10; Schreiben.

Stellen Sie sich in Ihrem ersten Fall a = 10; Als Abkürzung für A::a = 10; Und im zweiten Fall als Abkürzung für this->a = 10; Vor, die seit dem Typ nicht kompilierbar ist von this ist const A*.

94
Bathsheba

Nach dem C++ Standard (9.2.3.2 Statische Datenelemente)

1 Ein statisches Datenelement ist nicht Teil der Unterobjekte einer Klasse ...

Und (9.2.2.1 Der this Zeiger)

1 Im Hauptteil einer nicht statischen (9.2.1) Elementfunktion ist das Schlüsselwort this ein Wertausdruck, dessen Wert die Adresse des Objekts ist, für das die Funktion aufgerufen wird. Der Typ davon in einer Elementfunktion einer Klasse X ist X *. Wenn die Mitgliedsfunktion als const deklariert ist, ist der Typ davon const X *, ...

Und endlich (9.2.2 Nicht statische Elementfunktionen)

3 ... wenn die Namenssuche (3.4) den Namen im ID-Ausdruck in ein nicht statisches nicht typisiertes Element einer Klasse C auflöst und wenn entweder der ID-Ausdruck potenziell ausgewertet wird oder C X oder eine Basisklasse ist von X wird der id-Ausdruck in einen Klassenmitgliedszugriffsausdruck (5.2.5) umgewandelt, indem (* this) (9.2.2.1) als Postfix-Ausdruck links vom. Operator.

Also in dieser Klassendefinition

class A 
{
  public:   
    static int a; 

    void set() const
    {
        a = 10;
    }
};

das statische Datenelement a ist kein Unterobjekt eines Objekts des Klassentyps, und der Zeiger this wird nicht für den Zugriff auf das statische Datenelement verwendet. Daher kann jede Elementfunktion, nicht statische Konstante oder Nichtkonstante oder statische Elementfunktion das Datenelement ändern, da es keine Konstante ist.

In dieser Klassendefinition

class A 
{
  public:   
    int a; 

    void set() const
    {
        a = 10;
    }
};

das nicht statische Datenelement a ist ein Unterobjekt eines Objekts des Klassentyps. Um in einer Member-Funktion darauf zuzugreifen, wird entweder eine Member-Zugriffssyntax dieser Syntax verwendet. Sie dürfen keinen konstanten Zeiger this verwenden, um das Datenelement zu ändern. Und der Zeiger, der dies ist, hat tatsächlich den Typ const A * innerhalb der Funktion set, da die Funktion mit dem Qualifier const deklariert wird. Wenn die Funktion in diesem Fall kein Qualifikationsmerkmal hat, kann das Datenelement geändert werden.

21

Die Sache ist, dass, wenn eine Mitgliedsfunktion einer Klasse Aconst ist, der Typ von thisconst X* ist und somit verhindert, dass nicht statische Datenmitglieder geändert werden (Siehe zum Beispiel C++ - Standard ):

9.3.2 Der this Zeiger [class.this]

Im Hauptteil einer nicht statischen (9.3) Elementfunktion ist das Schlüsselwort this ein Wertausdruck, dessen Wert die Adresse des Objekts ist, für das die Funktion aufgerufen wird. Der Typ davon in einer Elementfunktion einer Klasse X ist X *. Wenn die Mitgliedsfunktion als const deklariert ist, lautet der Typ dieser Funktion const X *, ...

Wenn a ein nicht statisches Datenelement ist, ist a=10 dasselbe wie this->a = 10, was nicht zulässig ist, wenn der Typ von thisconst A* ist und a nicht deklariert wurde als mutable. Da void set() const den Typ von this zu const A* macht, ist dieser Zugriff nicht zulässig.

Wenn a dagegen ein statisches Datenelement ist, bezieht a=10this überhaupt nicht ein; und solange static int a für sich nicht als const deklariert wurde, ist die Anweisung a=10 zulässig.

13
Stephan Lechner

Das const-Qualifikationsmerkmal für eine Elementfunktion bedeutet, dass Sie non-mutable, non-staticKlassendatenelemente nicht ändern können.

1
Li Kui