Waarom kan een const-lidfunctie een statisch gegevenslid wijzigen?

In het volgende C++-programma werkt het wijzigen van een statisch gegevenslidvanuit een const-functie prima:

class A 
{
  public:   
    static int a; // static data member
    void set() const
    {
        a = 10;
    }
};

Maar het wijzigen van een niet-statisch gegevenslidvanuit een const-functie werkt niet:

class A 
{
  public:   
    int a; // non-static data member
    void set() const
    {
        a = 10;
    }
};

Waarom kan een constlidfunctie een staticgegevenslid wijzigen?


Antwoord 1, autoriteit 100%

Het is de regel, dat is alles. En met een goede reden.

De kwalificatie constop een lidfunctie betekent dat u niet-mutableniet-staticklasselidvariabelen kunt wijzigen.

Bij wijze van rationalisatie is de thispointer in een constgekwalificeerde lidfunctie een consttype, en thisis inherent gerelateerd aan een instantievan een klasse. staticleden zijn niet gerelateerd aan een klasse-instantie. U hebt geen instantie nodig om een ​​staticlid te wijzigen: u kunt dit in uw geval doen door A::a = 10;te schrijven.

Dus, in het eerste geval, denk aan a = 10;als afkorting voor A::a = 10;en in het tweede geval als afkorting voor this->a = 10;, die niet kan worden gecompileerd omdat het type thisconst A*is.


Antwoord 2, autoriteit 21%

Volgens de C++-standaard (9.2.3.2 Statische gegevensleden)

1 Een statisch gegevenslid maakt geen deel uit van de subobjecten van een klasse

En (9.2.2.1 De deze-aanwijzer)

1 In de hoofdtekst van een niet-statische (9.2.1) lidfunctie, het sleutelwoord
dit is een prvalue-expressie waarvan de waarde het adres van het object is
waarvoor de functie wordt aangeroepen. Het type hiervan in een lid
functie van een klasse X is X*. Als de lidfunctie is gedeclareerd
const, het type hiervan is const X*
,…

En eindelijk (9.2.2 Niet-statische ledenfuncties)

3 … als naam opzoeken (3.4) de naam in de id-expressie omzet in a
niet-statisch niet-type lid van een klasse C, en als ofwel de
id-expressie wordt mogelijk geëvalueerd of C is X of een basisklasse van X,
de id-expressie wordt getransformeerd in een class-lidtoegangsuitdrukking
(5.2.5) met (*this)(9.2.2.1) als de postfix-expressie voor de
links van de. operator.

Dus in deze klassedefinitie

class A 
{
  public:   
    static int a; 
    void set() const
    {
        a = 10;
    }
};

het statische gegevenslid ais geen subobject van een object van het klassetype en de aanwijzer thiswordt niet gebruikt om toegang te krijgen tot het statische gegevenslid. Dus elke lidfunctie, niet-statische constante of niet-constante, of een statische lidfunctie kan het gegevenslid wijzigen omdat het geen constante is.

In deze klassedefinitie

class A 
{
  public:   
    int a; 
    void set() const
    {
        a = 10;
    }
};

het niet-statische gegevenslid ais een subobject van een object van het klassetype. Om toegang te krijgen in een ledenfunctie wordt er ofwel een syntaxis voor ledentoegang van deze syntaxis geïmpliceerd. U mag geen constante aanwijzer thisgebruiken om het gegevenslid te wijzigen. En de aanwijzer die dit is, heeft inderdaad het type const A *binnen de functie setomdat de functie wordt gedeclareerd met de kwalificatie const. Als de functie geen kwalificatie had, zou in dit geval het gegevenslid kunnen worden gewijzigd.


Antwoord 3, autoriteit 13%

Het punt is dat als een lidfunctie van een klasse aconstis, het type thisconst X*, en voorkomt zo dat niet-statische gegevensleden worden gewijzigd (zie bijvoorbeeld C++-standaard):

9.3.2 De deze-aanwijzer [class.this]

In de hoofdtekst van een niet-statische (9.3) lidfunctie is het sleutelwoord this een prvalue-expressie waarvan
waarde is het adres van het object waarvoor de functie wordt aangeroepen.
Het type hiervan in een lidfunctie van een klasse X is X*. Als de
lidfunctie is gedeclareerd const, het type hiervan is const X*, …

Als aeen niet-statisch gegevenslid is, dan is a=10hetzelfde als this->a = 10, wat niet is toegestaan ​​als het type thisconst A*is en aniet is gedeclareerd als mutable. Dus, aangezien void set() consthet type thisconst A*maakt, is deze toegang niet toegestaan.

Als adaarentegen een statisch gegevenslid is, dan heeft a=10helemaal geen betrekking op this; en zolang static int aop zichzelf niet is gedeclareerd als const, is statement a=10toegestaan.


Antwoord 4

De kwalificatie constop een lidfunctiebetekent dat u non-mutable, non-staticniet kunt wijzigen leden van klasgegevens.

Other episodes