В следующей C++
программе изменение статического члена данных из const
функции работает нормально:
class A
{
public:
static int a; // static data member
void set() const
{
a = 10;
}
};
Но изменение нестатического члена данных из const
функции не работает:
class A
{
public:
int a; // non-static data member
void set() const
{
a = 10;
}
};
Почему const
функция-член может изменять static
член данных?
const
функция-член объекта не может изменять этот единственный объект . Он может изменять другие объекты того же класса илиstatic
данные, связанные с классом, а не его конкретный экземпляр. (Илиmutable
члены данных, которые были созданы, чтобы быть исключением из этого правила.)Ответы:
Это правило, вот и все. И не зря.
const
Классификатор на функции члена означает , что вы не можете изменить Непро-mutable
Непро-static
переменных - членов класса.Предлагая некоторую рационализацию,
this
указатель вconst
квалифицированной функции-члене являетсяconst
типом иthis
по своей сути связан с экземпляром класса.static
члены не связаны с экземпляром класса. Вам не нужен экземпляр для измененияstatic
члена: вы можете сделать это в вашем случае, написавA::a = 10;
.Итак, в первом случае считайте
a = 10;
это сокращением,A::a = 10;
а во втором - сокращением дляthis->a = 10;
, которое не компилируется, поскольку типthis
isconst A*
.источник
this
указатель, он будет иметь типconst A* const
вconst
случае.this
- это значение типа указателя. Prvalues неклассовых типов никогда не квалифицируются cv.Согласно стандарту C ++ (9.2.3.2 Статические элементы данных)
И (9.2.2.1 Указатель this)
И наконец (9.2.2 Нестатические функции-члены)
Таким образом, в этом определении класса
class A { public: static int a; void set() const { a = 10; } };
статический член данных
a
не является подобъектом объекта типа класса, и указательthis
не используется для доступа к статическому члену данных. Таким образом, любая функция-член, нестатическая константа или неконстанта, или статическая функция-член может изменить член данных, потому что он не является константой.В этом определении класса
class A { public: int a; void set() const { a = 10; } };
нестатический член данных
a
является подобъектом объекта типа класса. Для доступа к нему в функции-члене используется либо подразумевается синтаксис доступа к члену этого синтаксиса. Вы не можете использовать постоянный указательthis
для изменения элемента данных. И указатель this действительно имеет типconst A *
внутри функции,set
потому что функция объявлена с квалификаторомconst
. Если бы функция не имела квалификатора, в этом случае член данных можно было бы изменить.источник
Дело в том, что если функция-член класса
A
isconst
, то типthis
isconst X*
и тем самым предотвращает изменение нестатических элементов данных (см., Например, стандарт C ++ ):Если
a
это нестатический член данных, тоa=10
это то же самое, что иthis->a = 10
, что недопустимо, если типthis
isconst A*
иa
не был объявлен какmutable
. Таким образом, посколькуvoid set() const
делает типthis
существаconst A*
, этот доступ не разрешен.a
Напротив, if - статический член данных, тогдаa=10
вообще не задействованthis
; и покаstatic int a
само по себе не было объявлено какconst
, операторa=10
разрешен.источник
const
Отборочный на величинуХи функции члена означает , что вы не можете изменитьnon-mutable
,non-static
член класса .источник