C++ 在类的函数中使用“const”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2157458/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using 'const' in class's functions
提问by ggg
I've seen a lot of uses of the const keyword put after functions in classes, so i wanted to know what was it about. I read up smth at here: http://duramecho.com/ComputerInformation/WhyHowCppConst.html.
我在类中的函数之后看到了很多 const 关键字的用法,所以我想知道它是关于什么的。我在这里阅读了 smth:http: //duramecho.com/ComputerInformation/WhyHowCppConst.html。
It says that const is used because the function "can attempt to alter any member variables in the object" . If this is true, then should it be used everywhere, because i don't want ANY of the member variables to be altered or changed in any way.
它说使用 const 是因为该函数“可以尝试更改对象中的任何成员变量”。如果这是真的,那么它应该在任何地方使用,因为我不希望以任何方式更改或更改任何成员变量。
class Class2
{ void Method1() const;
int MemberVariable1;}
So, what is the real definition and use of const ?
那么, const 的真正定义和用途是什么?
回答by R Samuel Klatchko
A const method can be called on a const object:
可以在 const 对象上调用 const 方法:
class CL2
{
public:
void const_method() const;
void method();
private:
int x;
};
const CL2 co;
CL2 o;
co.const_method(); // legal
co.method(); // illegal, can't call regular method on const object
o.const_method(); // legal, can call const method on a regulard object
o.method(); // legal
Furthermore, it also tells the compiler that the const method should not be changing the state of the object and will catch those problems:
此外,它还告诉编译器 const 方法不应该改变对象的状态,并将捕获这些问题:
void CL2::const_method() const
{
x = 3; // illegal, can't modify a member in a const object
}
There is an exception to the above rule by using the mutable modifier, but you should first get good at const correctness before you venture into that territory.
使用 mutable 修饰符对上述规则有一个例外,但是在冒险进入该领域之前,您应该首先熟悉 const 的正确性。
回答by John Dibling
Others have answered the technical side of your question about const member functions, but there is a bigger picture here -- and that is the idea of const correctness.
其他人已经回答了您关于 const 成员函数的问题的技术方面,但这里有一个更大的图景——这就是const 正确性的想法。
Long story short, const correctness is about clarifying and enforcing the semantics of your code. Take a simple example. Look at this function declaration:
长话短说,const 正确性是关于澄清和强制执行代码的语义。举个简单的例子。看看这个函数声明:
bool DoTheThing(char* message);
Suppose someone else wrote this function and you need to call it. Do you know what DoTheThing()
does to your char buffer? Maybe it just logs the message to a file, or maybe it changes the string. You can't tell what the semantics of the call are by just looking at the function declaration. If the function doesn't modify the string, then the declaration is const incorrect.
假设其他人编写了此函数,而您需要调用它。你知道DoTheThing()
你的字符缓冲区有什么作用吗?也许它只是将消息记录到一个文件中,或者它可能会更改字符串。您无法通过查看函数声明来判断调用的语义是什么。如果函数不修改字符串,则声明是 const 不正确的。
There's practical value to making your functions const correct, too. Namely, depending on the context of the call, you might not be able to call const-incorrect functions without some trickery. For example, assume that you know that DoTheThing()
doesn't modify the contents of the string passed to it, and you have this code:
使您的函数 const 正确也有实用价值。也就是说,根据调用的上下文,您可能无法在没有一些技巧的情况下调用 const 不正确的函数。例如,假设您知道DoTheThing()
不会修改传递给它的字符串的内容,并且您有以下代码:
void MyFunction()
{
std::string msg = "Hello, const correctness";
DoTheThing(msg.c_str());
}
The above code won't compile because msg.c_str()
returns a const char*
. In order to get this code to compile, you would have to do something like this:
上面的代码不会编译,因为msg.c_str()
返回一个const char*
. 为了编译此代码,您必须执行以下操作:
void MyFunction()
{
std::string msg = "Hello, const correctness";
DoTheThing(msg.begin());
}
...or even worse:
……甚至更糟:
void MyFunction()
{
std::string msg = "Hello, const correctness";
DoTheThing(const_cast<char*>(msg.c_str()));
}
neither of which, arguably, are 'better' than the original code. But because DoTheThing()
was written in a const-incorrect way, you have to bend your code around it.
可以说,这两个都不比原始代码“更好”。但是因为DoTheThing()
是以一种不正确的方式编写的,所以你必须围绕它弯曲你的代码。
回答by Ben Supnik
const, when attached to a non-static class method, tells the compiler that your function doesn't modify the internal state of the object.
const,当附加到非静态类方法时,告诉编译器您的函数不会修改对象的内部状态。
This is useful in two ways:
这在两个方面很有用:
- If you do write code that changes internal state in your const method, the compiler catches the error, moving a programming error from run-time to compile-time.
- If client code calls a non-const method on a constant pointer, the compiler catches the error, ensuring the "chain of not changing things" is maintained.
- 如果您确实编写了更改 const 方法中内部状态的代码,编译器会捕获错误,将编程错误从运行时移至编译时。
- 如果客户端代码在常量指针上调用非常量方法,编译器会捕获错误,确保维护“不改变事物的链”。
Typically you want to declare all non-mutating non-static class methods as const. This allows calling code to use the const qualifier on pointers, and it helps catch mistakes.
通常,您希望将所有非变异非静态类方法声明为 const。这允许调用代码在指针上使用 const 限定符,并有助于捕获错误。
Typical C++: you can declare a class member variable "mutable" and then change it evenfrom a const method.
典型的 C++:您可以声明一个类成员变量“可变”,然后甚至从 const 方法更改它。
回答by mikelong
The meaning is that you guarantee to clients calling a const function member that the state of the object will not change. So when you say a member function is const it means that you do not change any of the objects member variables during the function call.
这意味着您向调用 const 函数成员的客户端保证对象的状态不会改变。因此,当您说成员函数是 const 时,这意味着您在函数调用期间不会更改任何对象成员变量。
回答by mikelong
It's quite unusual not to want to have any member variables changed, but if that's what your class requires, then you should make all your member functions const.
不想改变任何成员变量是很不寻常的,但如果这是您的类所需要的,那么您应该将所有成员函数都设置为 const。
However, you probably do want to change at least some members:
但是,您可能确实希望更改至少一些成员:
class A {
private:
int val;
public:
A() : val(0) {}
void Inc() { val++; }
int GetVal() const { return val; };
};
Now if I create two instances of A:
现在,如果我创建 A 的两个实例:
A a1;
const A a2;
I can say:
我可以说:
a1.GetVal();
a2.GetVal();
but I can only say:
但我只能说:
a1.Inc();
trying to change the value of a constant object:
试图改变一个常量对象的值:
a2.Inc();
gives a compilation error.
给出编译错误。
回答by John Feminella
If this is true, then should it be used everywhere, because i don't want ANY of the member variables to be altered or changed in any way?
如果这是真的,那么它是否应该在任何地方使用,因为我不希望以任何方式更改或更改任何成员变量?
Well, no. Sometimes you dowant instance methods to modify members. For example, any set method will obviously need to set variables, so it's not the case that you should put const everywhere. But if your object's state is totally immutable, first consider whether it might not be better to have no instances at all (i.e., a static class), and if that's not the case, then make everything const
.
嗯,不。有时您确实需要实例方法来修改成员。例如,任何 set 方法显然都需要设置变量,因此您不应该将 const 放在任何地方。但是,如果您的对象的状态是完全不可变的,首先要考虑完全没有实例(即静态类)是否更好,如果不是这种情况,则将所有内容都设置为const
.
回答by Mathieu Pagé
The const keyword used after a method indicate that this method doesn't modify the object on which it's called. This way, this method can be called on a const version of the object.
方法后使用的 const 关键字表示此方法不会修改调用它的对象。这样,可以在对象的 const 版本上调用此方法。