给定这样的声明:
class A {
public:
void Foo() const;
};
这是什么意思?
谷歌出现了这个:
如果成员函数可以对 const (this) 对象进行操作,则应在其后使用 const 关键字声明成员函数。如果函数没有声明为 const,则 in 不能应用于 const 对象,并且编译器会给出错误信息。
但我觉得这有点令人困惑;有谁能把它说得更好吗?
谢谢。
给定这样的声明:
class A {
public:
void Foo() const;
};
这是什么意思?
谷歌出现了这个:
如果成员函数可以对 const (this) 对象进行操作,则应在其后使用 const 关键字声明成员函数。如果函数没有声明为 const,则 in 不能应用于 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
. 因此,您无法在const
内部调用非函数,A::Foo
也无法更改成员变量的值。
为了说明,Foo()可能不会调用A::SetState
,因为它被声明为 non- const
,A::GetState
但是可以,因为它是显式声明const
的。除非使用关键字声明,否则成员m_nState
也不能更改mutable
。
这种用法的一个例子const
是“getter”函数获取成员变量的值。
@1800 信息:我忘了可变的!
关键字指示编译器接受对成员变量的mutable
修改,否则会导致编译器错误。当函数需要修改状态但无论修改如何都认为对象在逻辑上一致(常量)时使用它。
这不是一个答案,只是一个侧面评论。强烈建议尽可能多地声明变量和常量const
。
const
有一种通过代码传播的有趣方式。因此,const
尽早并尽可能多地开始使用是一个非常好的主意。决定const
在游戏后期开始对代码进行修改可能会很痛苦(容易,但很烦人)。如果您使用的是静态语言,编译时检查是一个好主意,尽可能多地使用它们……这实际上只是另一种测试。
带限定符的函数const
不允许修改任何成员变量。例如:
class A
{
int x;
mutable int y;
void f() const
{
x = 1; // error
y = 1; // ok because y is mutable
}
};
C++ 对象可以声明为 const:
const A obj = new A();
当一个对象是 const 时,可以在该对象上调用的唯一成员函数是声明为 const 的函数。将对象设为 const 可以解释为将对象设为只读。const 对象不能更改,即对象的任何数据成员都不能更改。声明成员函数 const 意味着不允许该函数对对象的数据成员进行任何更改。
从经验中建议的两个最佳实践:
(1)尽可能声明 const 函数。起初,我发现这只是额外的工作,但后来我开始将我的对象传递给具有 f(const Object& o) 之类签名的函数,然后编译器突然在 f 中的一行,例如 o.GetAValue(),因为我没有将 GetAValue 标记为 const 函数。这会让您感到惊讶,尤其是当您将某些东西子类化并且不将您的虚拟方法版本标记为 const 时 - 在这种情况下,编译可能会在您之前从未听说过的为基类编写的某些函数上失败。
(2)在可行的情况下避免使用可变变量。一个诱人的陷阱可能是允许读取操作改变状态,例如,如果您正在构建一个执行惰性或异步 i/o 操作的“智能”对象。如果你可以只用一个小的可变变量(如布尔值)来管理它,那么根据我的经验,这是有道理的。但是,如果您发现自己将每个成员变量标记为可变以保持某些操作 const,那么您就违背了 const 关键字的目的。可能出错的是一个认为它没有改变你的类的函数(因为它只调用 const 方法)我在你的代码中调用了一个错误,甚至可能需要付出很多努力才能意识到这个错误在你的类中,
const 有一种通过代码传播的有趣方式。因此,尽早并尽可能多地开始使用 const 是一个非常好的主意。决定在游戏后期开始对代码进行 const 化可能会很痛苦(容易,但很烦人)。
此外,如果应该是 const 的方法不是,您将很容易遇到问题!这也将渗透到代码中,并使其变得越来越糟。
这将导致该方法无法更改对象的任何成员变量