C++ “const”最后在类的函数声明中的含义?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/751681/
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
Meaning of 'const' last in a function declaration of a class?
提问by Mats Fredriksson
What is the meaning of const
in declarations like these? The const
confuses me.
const
像这样的声明是什么意思?这const
让我很困惑。
class foobar
{
public:
operator int () const;
const char* foo() const;
};
回答by Mats Fredriksson
When you add the const
keyword to a method the this
pointer will essentially become a pointer to const
object, and you cannot therefore change any member data. (Unless you use mutable
, more on that later).
当您将const
关键字添加到方法时,this
指针本质上将成为指向const
对象的指针,因此您不能更改任何成员数据。(除非您使用mutable
,稍后会详细介绍)。
The const
keyword is part of the functions signature which means that you can implement two similar methods, one which is called when the object is const
, and one that isn't.
该const
关键字是函数的签名,这意味着你可以实现两个类似的方法,当一个对象是被称为的一部分const
,和一个不是。
#include <iostream>
class MyClass
{
private:
int counter;
public:
void Foo()
{
std::cout << "Foo" << std::endl;
}
void Foo() const
{
std::cout << "Foo const" << std::endl;
}
};
int main()
{
MyClass cc;
const MyClass& ccc = cc;
cc.Foo();
ccc.Foo();
}
This will output
这将输出
Foo
Foo const
In the non-const method you can change the instance members, which you cannot do in the const
version. If you change the method declaration in the above example to the code below you will get some errors.
在非常量方法中,您可以更改实例成员,而在const
版本中不能这样做。如果将上面示例中的方法声明更改为下面的代码,则会出现一些错误。
void Foo()
{
counter++; //this works
std::cout << "Foo" << std::endl;
}
void Foo() const
{
counter++; //this will not compile
std::cout << "Foo const" << std::endl;
}
This is not completely true, because you can mark a member as mutable
and a const
method can then change it. It's mostly used for internal counters and stuff. The solution for that would be the below code.
这并不完全正确,因为您可以将成员标记为mutable
,const
然后方法可以更改它。它主要用于内部计数器和东西。解决方案是下面的代码。
#include <iostream>
class MyClass
{
private:
mutable int counter;
public:
MyClass() : counter(0) {}
void Foo()
{
counter++;
std::cout << "Foo" << std::endl;
}
void Foo() const
{
counter++; // This works because counter is `mutable`
std::cout << "Foo const" << std::endl;
}
int GetInvocations() const
{
return counter;
}
};
int main(void)
{
MyClass cc;
const MyClass& ccc = cc;
cc.Foo();
ccc.Foo();
std::cout << "Foo has been invoked " << ccc.GetInvocations() << " times" << std::endl;
}
which would output
哪个会输出
Foo
Foo const
Foo has been invoked 2 times
回答by Blair Conrad
The const means that the method promises not to alter any members of the class. You'd be able to execute the object's members that are so marked, even if the object itself were marked const
:
const 意味着该方法承诺不会更改类的任何成员。即使对象本身被标记,您也可以执行被标记的对象成员const
:
const foobar fb;
fb.foo();
would be legal.
将是合法的。
See How many and which are the uses of “const” in C++?for more information.
请参阅C++ 中“const”的用途有多少?想要查询更多的信息。
回答by JaredPar
The const
qualifier means that the methods can be called on any value of foobar
. The difference comes when you consider calling a non-const method on a const object. Consider if your foobar
type had the following extra method declaration:
在const
预选赛的手段,该方法可以在任何值调用foobar
。当您考虑在 const 对象上调用非常量方法时,就会出现差异。考虑您的foobar
类型是否具有以下额外的方法声明:
class foobar {
...
const char* bar();
}
The method bar()
is non-const and can only be accessed from non-const values.
该方法bar()
是非常量的,只能从非常量值访问。
void func1(const foobar& fb1, foobar& fb2) {
const char* v1 = fb1.bar(); // won't compile
const char* v2 = fb2.bar(); // works
}
The idea behind const
though is to mark methods which will not alter the internal state of the class. This is a powerful concept but is not actually enforceable in C++. It's more of a promise than a guarantee. And one that is often broken and easily broken.
背后的想法const
是标记不会改变类内部状态的方法。这是一个强大的概念,但实际上并不能在 C++ 中强制执行。与其说是保证,不如说是一种承诺。和一个经常坏和容易坏的。
foobar& fbNonConst = const_cast<foobar&>(fb1);
回答by Mykola Golubyev
These const mean that compiler will Error if the method 'with const' changes internal data.
这些 const 意味着如果“with const”方法更改内部数据,编译器将出错。
class A
{
public:
A():member_()
{
}
int hashGetter() const
{
state_ = 1;
return member_;
}
int goodGetter() const
{
return member_;
}
int getter() const
{
//member_ = 2; // error
return member_;
}
int badGetter()
{
return member_;
}
private:
mutable int state_;
int member_;
};
The test
考试
int main()
{
const A a1;
a1.badGetter(); // doesn't work
a1.goodGetter(); // works
a1.hashGetter(); // works
A a2;
a2.badGetter(); // works
a2.goodGetter(); // works
a2.hashGetter(); // works
}
Read thisfor more information
阅读本文了解更多信息
回答by Alnitak
Blair's answer is on the mark.
布莱尔的回答恰到好处。
However note that there is a mutable
qualifier which may be added to a class's data members. Any member so marked canbe modified in a const
method without violating the const
contract.
但是请注意,有一个mutable
限定符可以添加到类的数据成员中。任何如此标记的成员都可以在const
不违反const
合同的情况下以一种方法进行修改。
You might want to use this (for example) if you want an object to remember how many times a particular method is called, whilst not affecting the "logical" constness of that method.
如果您希望对象记住调用特定方法的次数,同时不影响该方法的“逻辑”常量,则您可能想要使用它(例如)。
回答by Nan Xiao
Meaning of a Const Member Functionin C++ Common Knowledge: Essential Intermediate Programminggives a clear explanation:
一个const成员函数的意义在C ++常识:基本中级设计给出了明确的解释:
The type of the this pointer in a non-const member function of a class X is X * const. That is, it's a constant pointer to a non-constant X (see Const Pointers and Pointers to Const [7, 21]). Because the object to which this refers is not const, it can be modified. The type of this in a const member function of a class X is const X * const. That is, it's a constant pointer to a constant X. Because the object to which this refers is const, it cannot be modified. That's the difference between const and non-const member functions.
类 X 的非常量成员函数中 this 指针的类型为 X * const。也就是说,它是一个指向非常量 X 的常量指针(参见 Const Pointers 和 Pointers to Const [7, 21])。因为 this 指向的对象不是 const,所以可以修改。类 X 的 const 成员函数中的 this 类型为 const X * const。也就是说,它是一个指向常量 X 的常量指针。因为 this 指向的对象是常量,所以它不能被修改。这就是 const 和非常量成员函数之间的区别。
So in your code:
所以在你的代码中:
class foobar
{
public:
operator int () const;
const char* foo() const;
};
You can think it as this:
你可以这样想:
class foobar
{
public:
operator int (const foobar * const this) const;
const char* foo(const foobar * const this) const;
};
回答by Matrix Buster
when you use const
in the method signature (like your said: const char* foo() const;
) you are telling the compiler that memory pointed to by this
can't be changed by this method (which is foo
here).
当您const
在方法签名中使用时(如您所说const char* foo() const;
的:),您是在告诉编译器指向的内存this
不能被此方法(foo
此处)更改。
回答by coder3101
I would like to add the following point.
我想补充以下几点。
You can also makeit a const &
and const &&
你也可以把它变成一个const &
和const &&
So,
所以,
struct s{
void val1() const {
// *this is const here. Hence this function cannot modify any member of *this
}
void val2() const & {
// *this is const& here
}
void val3() const && {
// The object calling this function should be const rvalue only.
}
void val4() && {
// The object calling this function should be rvalue reference only.
}
};
int main(){
s a;
a.val1(); //okay
a.val2(); //okay
// a.val3() not okay, a is not rvalue will be okay if called like
std::move(a).val3(); // okay, move makes it a rvalue
}
Feel free to improve the answer. I am no expert
随意改进答案。我不是专家
回答by Chandra Shekhar
The constkeyword used with the function declaration specifies that it is a const member functionand it will not be able to changethe data members of the object.
与函数声明一起使用的const关键字指定它是一个const 成员函数,并且不能更改对象的数据成员。
回答by qwr
https://isocpp.org/wiki/faq/const-correctness#const-member-fns
https://isocpp.org/wiki/faq/const-correctness#const-member-fns
What is a "
const
member function"?A member function that inspects (rather than mutates) its object.
A
const
member function is indicated by aconst
suffix just after the member function's parameter list. Member functions with aconst
suffix are called “const member functions” or “inspectors.” Member functions without aconst
suffix are called “non-const member functions” or “mutators.”class Fred { public: void inspect() const; // This member promises NOT to change *this void mutate(); // This member function might change *this }; void userCode(Fred& changeable, const Fred& unchangeable) { changeable.inspect(); // Okay: doesn't change a changeable object changeable.mutate(); // Okay: changes a changeable object unchangeable.inspect(); // Okay: doesn't change an unchangeable object unchangeable.mutate(); // ERROR: attempt to change unchangeable object }
The attempt to call
unchangeable.mutate()
is an error caught at compile time. There is no runtime space or speed penalty forconst
, and you don't need to write test-cases to check it at runtime.The trailing
const
oninspect()
member function should be used to mean the method won't change the object's abstract(client-visible) state. That is slightly different from saying the method won't change the “raw bits” of the object's struct. C++ compilers aren't allowed to take the “bitwise” interpretation unless they can solve the aliasing problem, which normally can't be solved (i.e., a non-const alias could exist which could modify the state of the object). Another (important) insight from this aliasing issue: pointing at an object with a pointer-to-const doesn't guarantee that the object won't change; it merely promises that the object won't change via that pointer.
什么是“
const
成员函数”?检查(而不是改变)其对象的成员函数。
一个
const
成员函数由表示const
后缀只是成员函数的参数列表之后。带有const
后缀的成员函数称为“const 成员函数”或“检查员”。没有const
后缀的成员函数称为“非常量成员函数”或“mutators”。class Fred { public: void inspect() const; // This member promises NOT to change *this void mutate(); // This member function might change *this }; void userCode(Fred& changeable, const Fred& unchangeable) { changeable.inspect(); // Okay: doesn't change a changeable object changeable.mutate(); // Okay: changes a changeable object unchangeable.inspect(); // Okay: doesn't change an unchangeable object unchangeable.mutate(); // ERROR: attempt to change unchangeable object }
尝试调用
unchangeable.mutate()
是在编译时捕获的错误。没有运行时空间或速度损失const
,并且您不需要编写测试用例来在运行时检查它。尾部
const
上inspect()
成员函数应用于表示该方法不会改变该对象的抽象(客户端可见的)的状态。这与说该方法不会更改对象结构的“原始位”略有不同。C++ 编译器不允许采用“按位”解释,除非它们可以解决通常无法解决的别名问题(即,可能存在可以修改对象状态的非常量别名)。这个别名问题的另一个(重要)见解是:使用指向常量的指针指向一个对象并不能保证该对象不会改变;它只是承诺对象不会通过该指针改变。