当与C ++中的方法一起使用时,const运算符的含义是什么?

时间:2008-09-08 02:20:20

标签: c++

给出这样的声明:

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

这是什么意思?

谷歌出现了这个:

  

如果成员函数可以在const(this)对象上运行,则应使用const关键字声明它们。如果函数未声明为const,则无法应用于const对象,并且编译器将给出错误消息。

但我觉得有些混乱;谁可以把它放在更好的条件下?

感谢。

7 个答案:

答案 0 :(得分:12)

考虑班级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的状态。因此,您无法在const内调用非A::Foo函数,也无法更改成员变量的值。

为了说明, Foo()可能不会调用A::SetState,因为它被声明为非constA::GetState但是可以,因为它是显式声明的{ {1}}。除非使用关键字const声明成员,否则不得更改成员m_nState

mutable的这种用法的一个例子是'getter'函数来获取成员变量的值。

  

@ 1800信息:我忘了可变!

const关键字指示编译器接受对成员变量的修改,否则会导致编译器错误。它在函数需要修改状态时使用,但无论修改如何,对象都被认为是逻辑一致的(常量)。

答案 1 :(得分:5)

这不是一个答案,只是一个评论。建议尽可能高度来声明变量和常量const

  1. 这会将您的意图传达给您的班级用户(甚至/尤其是您自己)。
  2. 编译器会让您对这些意图保持诚实。 - 就像编译器检查文档一样。
  3. 根据定义,这可以防止您不期望的状态更改,并且可能允许您在方法中做出合理的假设。
  4. const有一种传播代码的有趣方式。因此,尽可能早地开始使用const是一个非常好的主意。决定开始const - 在游戏后期使用你的代码可能很痛苦(容易,但很烦人)。
  5. 如果你正在使用一种静态的语言,编译时间检查,尽可能多地使用它们是一个好主意...它只是另一种测试。

答案 2 :(得分:3)

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

class A
{
    int x;
    mutable int y;

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

答案 3 :(得分:2)

C ++对象可以声明为const:

const A obj = new A();

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

答案 4 :(得分:2)

两个建议的经验最佳实践:

(1)尽可能声明const函数。起初,我发现这只是额外的工作,但后来我开始将我的对象传递给具有f(const Object& o)等签名的函数,并且突然编译器在f中的一行上进行了barfed,例如o.GetAValue(),因为我没有将GetAValue标记为const函数。这可能会让你感到惊讶,尤其是当你继承某些东西并且不将你的虚拟方法版本标记为const时 - 在这种情况下,编译可能会失败,因为在为基类编写之前,你从未听说过某些函数。

(2)在可行时避免使用可变变量。诱人陷阱可以允许读取操作改变状态,例如,如果您正在构建一个执行惰性或异步I / O操作的“智能”对象。如果你只用一个小的可变变量(比如bool)来管理它,那么根据我的经验,这是有道理的。但是,如果你发现自己将每个成员变量标记为可变,以便保留一些操作const,那么你就是在破坏const关键字的目的。可能出错的是,一个认为它不会改变你的类的函数(因为它只调用const方法)我会在你的代码中调用一个bug,而且你的类中可能需要付出很多努力来实现这个bug,因为另一个编码器(正确地)假设您的数据是const,因为他或她只调用const方法。

答案 5 :(得分:2)

  

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

此外,如果不应该是const的方法,你很容易遇到问题!这也将在代码中蔓延,并使其变得越来越糟。

答案 6 :(得分:1)

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