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 const
lidfunctie een static
gegevenslid wijzigen?
Antwoord 1, autoriteit 100%
Het is de regel, dat is alles. En met een goede reden.
De kwalificatie const
op een lidfunctie betekent dat u niet-mutable
niet-static
klasselidvariabelen kunt wijzigen.
Bij wijze van rationalisatie is de this
pointer in een const
gekwalificeerde lidfunctie een const
type, en this
is inherent gerelateerd aan een instantievan een klasse. static
leden zijn niet gerelateerd aan een klasse-instantie. U hebt geen instantie nodig om een static
lid 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 this
const 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 a
is geen subobject van een object van het klassetype en de aanwijzer this
wordt 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 a
is 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 this
gebruiken om het gegevenslid te wijzigen. En de aanwijzer die dit is, heeft inderdaad het type const A *
binnen de functie set
omdat 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 a
const
is, het type this
const 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 a
een niet-statisch gegevenslid is, dan is a=10
hetzelfde als this->a = 10
, wat niet is toegestaan als het type this
const A*
is en a
niet is gedeclareerd als mutable
. Dus, aangezien void set() const
het type this
const A*
maakt, is deze toegang niet toegestaan.
Als a
daarentegen een statisch gegevenslid is, dan heeft a=10
helemaal geen betrekking op this
; en zolang static int a
op zichzelf niet is gedeclareerd als const
, is statement a=10
toegestaan.
Antwoord 4
De kwalificatie const
op een lidfunctiebetekent dat u non-mutable
, non-static
niet kunt wijzigen leden van klasgegevens.