C++ 当与C+中的方法一起使用时,const运算符意味着什么+;?

C++ 当与C+中的方法一起使用时,const运算符意味着什么+;?,c++,C++,给出这样的声明: class A { public: void Foo() const; }; 这是什么意思 谷歌发现了这个: 如果成员函数可以对const(this)对象进行操作,则应在其后面声明const关键字。如果函数未声明为const,则in不能应用于const对象,编译器将给出错误消息 但我觉得这有点令人困惑;有人能用更好的语言来表达吗 谢谢 这将导致方法无法更改对象的任何成员变量带有const限定符的函数不允许修改任何成员变量。例如: class A { int x

给出这样的声明:

class A {
public:
    void Foo() const;
};
这是什么意思

谷歌发现了这个:

如果成员函数可以对const(this)对象进行操作,则应在其后面声明const关键字。如果函数未声明为const,则in不能应用于const对象,编译器将给出错误消息

但我觉得这有点令人困惑;有人能用更好的语言来表达吗


谢谢

这将导致方法无法更改对象的任何成员变量

带有
const
限定符的函数不允许修改任何成员变量。例如:

class A
{
    int x;
    mutable int y;

    void f() const
    {
      x = 1; // error
      y = 1; // ok because y is mutable
    }
};

C++对象可以声明为常量:

const A obj = new A();

当一个对象是const时,可以在该对象上调用的唯一成员函数是声明为const的函数。将对象设为常量可以解释为将对象设为只读。常量对象不能更改,即对象的任何数据成员都不能更改。声明成员函数const意味着不允许该函数对对象的数据成员进行任何更改。

考虑类
a
的变化

class A {
public:
    void Foo() const;
    void Moo();

private:
    int m_nState; // Could add mutable keyword if desired
    int GetState() const   { return m_nState; }
    void SetState(int val) { m_nState = val; }
};

const A *A1 = new A();
A *A2 = new A();

A1->Foo(); // OK
A2->Foo(); // OK

A1->Moo(); // Error - Not allowed to call non-const function on const object instance
A2->Moo(); // OK
函数声明中的
const
关键字向编译器表明,函数在合同中有义务不修改
a
的状态。因此,您无法调用
A::Foo
中的非
const
函数,也无法更改成员变量的值

举例来说,Foo()可能不会调用
A::SetState
,因为它被声明为非
const
A::GetState
,但是可以,因为它被显式声明为
const
。成员
m_nState
也不能更改,除非使用关键字
mutable
声明

使用
const
的一个例子是“getter”函数获取成员变量的值

@1800信息:我忘了易变


mutable
关键字指示编译器接受对成员变量的修改,否则会导致编译器错误。当函数需要修改状态,但不管修改情况如何,对象都被视为逻辑一致(常量)时,使用它。

这不是答案,只是一个旁注。强烈建议尽可能多地声明变量和常量
const

  • 这会将您的意图传达给类用户(甚至/尤其是您自己)
  • 编译器会让你对这些意图保持诚实i、 这就像编译器检查的文档
  • 根据定义,这可以防止您没有预料到的状态更改,并且可能允许您在方法中做出合理的假设
  • const
    有一种通过代码传播的有趣方式。因此,尽早且尽可能频繁地开始使用
    const
    是一个非常好的主意。决定开始
    const
    -如果在游戏后期使用代码可能会很痛苦(很容易,但很烦人)

  • 如果您使用的是带有静态编译时检查的语言,那么尽可能多地使用它们是一个好主意。。。实际上,这只是另一种测试。

    根据经验建议了两种最佳实践:

    (1) 尽可能声明常量函数。起初,我发现这只是额外的工作,但后来我开始将我的对象传递给带有签名的函数,如f(const Object&o),然后编译器突然在f中的一行上吐出,如o.GetAValue(),因为我没有将GetAValue标记为const函数。这可能会让您感到惊讶,尤其是当您将某个对象子类化,并且没有将虚拟方法的版本标记为const时——在这种情况下,编译可能会在为基类编写的函数上失败

    (2) 在可行的情况下避免可变变量。一个诱人的陷阱可能是允许读取操作改变状态,例如,如果您正在构建一个执行惰性或异步i/o操作的“智能”对象。如果您只需要一个小的可变变量(比如bool)就可以处理这个问题,那么根据我的经验,这是有意义的。然而,如果您发现自己为了保持某些操作常量而将每个成员变量都标记为可变的,那么您就违背了const关键字的目的。可能出现的错误是,一个认为它没有改变你的类(因为它只调用const方法)的函数调用了你代码中的一个bug,而且可能需要花费很多努力才能意识到这个bug在你的类中,因为另一个编码者(正确地)认为你的数据是const的,因为他或她只调用const方法

    const有一种通过代码传播的有趣方式。因此,尽早且尽可能频繁地开始使用const是一个非常好的主意。在游戏后期决定开始编译代码可能会很痛苦(很容易,但很烦人)


    此外,如果不使用应为常量的方法,您将很容易遇到问题!这也会在代码中蔓延,使其变得越来越糟糕。

    错误。。。常数A*obj=新的A()。。。你忘了“星星”…:-)