首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么常量成员函数可以修改静态数据成员?

为什么常量成员函数可以修改静态数据成员?
EN

Stack Overflow用户
提问于 2017-05-12 19:11:16
回答 4查看 9.3K关注 0票数 86

在下面的C++程序中,从函数修改静态数据成员const可以正常工作:

代码语言:javascript
运行
复制
class A 
{
  public:   
    static int a; // static data member

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

但是,从const函数修改非静态数据成员不起作用:

代码语言:javascript
运行
复制
class A 
{
  public:   
    int a; // non-static data member

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

为什么const static 成员函数可以修改数据成员?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-05-12 19:14:35

这是规则,仅此而已。这是有充分理由的。

成员函数上的const限定符意味着您不能修改非mutablestatic类成员变量。

通过提供一些合理的方法,const限定成员函数中的this指针是const类型,并且this本质上与类的实例相关。static成员与类实例无关。修改static成员不需要实例:在本例中,可以通过编写A::a = 10;来完成。

因此,在第一种情况下,将a = 10;视为A::a = 10;的简写,在第二种情况中,将其视为this->a = 10;的简写,由于this的类型为const A*,因此它是不可编译的。

票数 100
EN

Stack Overflow用户

发布于 2017-05-12 19:51:56

根据C++标准(9.2.3.2静态数据成员)

1静态数据成员is 不是类的子对象的一部分...

和(9.2.2.1 this指针)

1在非静态(9.2.1)成员函数体中,关键字this是一个prvalue表达式,其值是为其调用函数的对象的地址。类X的成员函数中的this类型是X*。如果成员函数声明为const,则其类型为const X*,...

最后(9.2.2非静态成员函数)

3...如果名称查找(3.4)将id表达式中的名称解析为某个类C的非静态非类型成员,并且如果id表达式可能被求值,或者C是X或X的基类,则使用(*this) (9.2.2.1)作为左侧的后缀表达式将id表达式转换为类成员访问表达式(5.2.5)。操作符。

因此,在这个类定义中

代码语言:javascript
运行
复制
class A 
{
  public:   
    static int a; 

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

静态数据成员a不是类类型的对象的子对象,并且指针this不用于访问静态数据成员。因此,任何成员函数,非静态常量或非常量,或静态成员函数都可以更改数据成员,因为它不是常量。

在这个类定义中

代码语言:javascript
运行
复制
class A 
{
  public:   
    int a; 

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

非静态数据成员a是类类型的对象的子对象。要在成员函数中访问它,可以使用隐含此语法的成员访问语法。不能使用常量指针this修改数据成员。在函数set中,指针this的类型为const A *,因为该函数是用限定符const声明的。如果函数没有限定符,则可以更改数据成员。

票数 21
EN

Stack Overflow用户

发布于 2017-05-12 19:32:49

问题是,如果类A的成员函数是const,那么this的类型就是const X*,从而防止非静态数据成员被更改(例如,C++ standard):

9.3.2此指针class.this

在非静态(9.3)成员函数体中,关键字this是一个prvalue表达式,它的值是为其调用函数的对象的地址。类X的成员函数中的this类型是X*。如果成员函数声明为const,则其类型为const X*,...

如果a是非静态数据成员,则a=10this->a = 10相同,如果this的类型为const A*并且a尚未声明为mutable,则不允许这样做。因此,由于void set() constthis的类型设置为const A*,因此不允许这种访问。

相反,如果a是一个静态数据成员,那么a=10根本不涉及this;只要static int a本身没有被声明为const,就允许使用语句a=10

票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43936404

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档