给出这样的声明:
class A {
public:
void Foo() const;
};
这是什么意思?
谷歌出现了这个:如果成员函数可以在const(this)对象上运行,则应使用const关键字声明它们。如果函数未声明为const,则无法应用于const对象,并且编译器将给出错误消息。
但我觉得有些混乱;谁可以把它放在更好的条件下?
感谢。
答案 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
,因为它被声明为非const
,A::GetState
但是可以,因为它是显式声明的{ {1}}。除非使用关键字const
声明成员,否则不得更改成员m_nState
。
mutable
的这种用法的一个例子是'getter'函数来获取成员变量的值。
@ 1800信息:我忘了可变!
const
关键字指示编译器接受对成员变量的修改,否则会导致编译器错误。它在函数需要修改状态时使用,但无论修改如何,对象都被认为是逻辑一致的(常量)。
答案 1 :(得分:5)
这不是一个答案,只是一个评论。建议尽可能高度来声明变量和常量const
。
const
有一种传播代码的有趣方式。因此,尽可能早地开始使用const
是一个非常好的主意。决定开始const
- 在游戏后期使用你的代码可能很痛苦(容易,但很烦人)。如果你正在使用一种静态的语言,编译时间检查,尽可能多地使用它们是一个好主意...它只是另一种测试。
答案 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)
将导致该方法无法更改对象的任何成员变量