Dlaczego funkcja const member może modyfikować statyczny element danych?

W następującym Programie C++ modyfikowanie elementu danych statycznych z funkcji const działa poprawnie:

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

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

Ale modyfikowanie niestatycznego elementu danych z const funkcji nie działa:

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

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

Dlaczego funkcja const może modyfikować element static danych?

Author: rsp, 2017-05-12

4 answers

Taka jest zasada, to wszystko. I nie bez powodu.

Kwalifikator const w funkcji member oznacza, że nie można modyfikować zmiennych klasy nie-mutable nie-static.

By oferować pewną racjonalizację, wskaźnik this w const kwalifikowanej funkcji członka jest typem const, a {[3] } jest z natury związany z instancją klasy. static Członkowie nie są powiązani z instancją klasy. Nie potrzebujesz instancji, aby zmodyfikować static członka: możesz to zrobić, w Twoim przypadku pisząc A::a = 10;.

Więc w pierwszym przypadku pomyśl o {[10] } jako o stenografii dla A::a = 10;, a w drugim przypadku pomyśl o tym jako o stenografii dla this->a = 10;, która nie jest kompilowalna, ponieważ typ this to const A*.

 93
Author: Bathsheba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-12 11:21:26

Zgodnie ze standardem C++ (9.2.3.2 statyczne elementy danych)

1 statyczny element danych nie jest częścią podobiektów klasy ...

I (9.2.2.1 ten wskaźnik)

1 w ciele niestatycznej (9.2.1) funkcji członka, słowo kluczowe jest to wyrażenie prvalue, którego wartością jest adres obiektu dla którego wywołana jest funkcja. Rodzaj tego w członku funkcja Klasy X to X*. Jeśli członek funkcja jest deklarowana const, typem tego jest const X * ,...

And at last (9.2.2 Non-static member functions)

3 ... jeśli name lookup (3.4) rozwiązuje nazwę w wyrażeniu id na nie-statyczny element typu jakiejś klasy C, a jeśli albo ID-wyrażenie jest potencjalnie oceniane lub C jest X lub klasą bazową X, wyrażenie id jest przekształcane w wyrażenie dostępu członka klasy (5.2.5) używając (*this) (9.2.2.1) jako postfix-wyrażenie do na lewo od ... centrala.

Tak więc w definicji tej klasy

class A 
{
  public:   
    static int a; 

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

Statyczny element danych a nie jest podobiektem obiektu typu class i wskaźnik this nie jest używany do uzyskania dostępu do statycznego elementu danych. Tak więc każda funkcja członka, stała niestatyczna lub stała, lub funkcja członka statycznego może zmienić element danych, ponieważ nie jest on stały.

W tej definicji klasy

class A 
{
  public:   
    int a; 

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

Niestatyczny element danych a jest podobiektem obiektu typu class. Aby uzyskać do niego dostęp w funkcji członka, używa się składni dostępu członka tej składni. Nie można używać stałego wskaźnika this do modyfikowania elementu danych. Wskaźnik ten rzeczywiście ma typ const A * wewnątrz funkcji set, ponieważ funkcja jest zadeklarowana kwalifikatorem const. Jeśli funkcja nie miała kwalifikatora w tym przypadku element danych może zostać zmieniony.

 21
Author: Vlad from Moscow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-13 05:15:58

Rzecz w tym, że jeśli funkcja członka klasy A jest const, to typ this jest const X*, a tym samym zapobiega zmianie niestatycznych członków danych (CF, na przykład standard C++ ):

9.3.2 wskaźnik ten [class.to]

W ciele niestatycznej (9.3) funkcji member, słowo kluczowe jest wyrażeniem prvalue, którego wartość jest adresem obiektu, dla którego wywołana jest funkcja. Rodzaj tego w członku funkcja Klasy X to X*. Jeśli funkcję składową deklaruje const, jej typem jest const X*, ...

Jeśli a jest niestatycznym elementem danych, to a=10 jest tym samym co this->a = 10, co nie jest dozwolone, jeśli typ this to const A* i a nie został zadeklarowany jako mutable. Tak więc, ponieważ void set() const sprawia, że typ this jest const A*, dostęp ten nie jest dozwolony.

Jeśli a jest statycznym składnikiem danych, to a=10 w ogóle nie obejmuje this i tak długo, jak static int a samo w sobie nie zostało zadeklarowane jako const, oświadczenie a=10 jest dozwolone.

 13
Author: Stephan Lechner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-12 11:35:03

Kwalifikator const W funkcji member oznacza, że nie można modyfikować non-mutable, non-static class data members .

 1
Author: Li Kui,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-14 07:31:22