689 c++ const declaration c++-faq
const
这些声明中的含义是什么?该const
混淆了我.
class foobar
{
public:
operator int () const;
const char* foo() const;
};
Run Code Online (Sandbox Code Playgroud)
Mat*_*son 897
将const
关键字添加到方法时,this
指针实际上将成为指向const
对象的指针,因此您无法更改任何成员数据.(除非你使用mutable
,稍后再详述).
该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();
}
Run Code Online (Sandbox Code Playgroud)
这将输出
Foo
Foo const
Run Code Online (Sandbox Code Playgroud)
在非const方法中,您可以更改实例成员,这在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;
}
Run Code Online (Sandbox Code Playgroud)
这不完全正确,因为您可以将成员标记为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++;
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" << endl;
}
Run Code Online (Sandbox Code Playgroud)
哪个会输出
Foo
Foo const
Foo has been invoked 2 times
Run Code Online (Sandbox Code Playgroud)
Bla*_*rad 180
const意味着该方法承诺不会改变该类的任何成员.即使对象本身已标记,您也可以执行标记为对象的成员const
:
const foobar fb;
fb.foo();
Run Code Online (Sandbox Code Playgroud)
是合法的.
在C++中查看"const"的用法和用途是什么?欲获得更多信息.
Jar*_*Par 46
在const
预选赛意味着这些方法可以在任何值调用foobar
.当您考虑在const对象上调用非const方法时会出现差异.考虑您的foobar
类型是否具有以下额外的方法声明:
class foobar {
...
const char* bar();
}
Run Code Online (Sandbox Code Playgroud)
该方法bar()
是非const的,只能从非const值访问.
void func1(const foobar& fb1, foobar& fb2) {
const char* v1 = fb1.bar(); // won't compile
const char* v2 = fb2.bar(); // works
}
Run Code Online (Sandbox Code Playgroud)
然而,背后的想法const
是标记不会改变类的内部状态的方法.这是一个强大的概念,但在C++中实际上是不可执行的.这更像是承诺而非保证.而且经常被打破并容易被打破的人.
foobar& fbNonConst = const_cast<foobar&>(fb1);
Run Code Online (Sandbox Code Playgroud)
Myk*_*yev 23
这些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_;
};
Run Code Online (Sandbox Code Playgroud)
考试
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
}
Run Code Online (Sandbox Code Playgroud)
阅读本文以获取更多信息
Aln*_*tak 12
布莱尔的回答很明显.
但请注意,有一个mutable
限定符可以添加到类的数据成员中.如此标记的任何成员都可以在const
不违反const
合同的情况下进行修改.
如果希望对象记住调用特定方法的次数,而不影响该方法的"逻辑"常量,则可能需要使用此(例如).
一个const成员函数的意义在C++常识:基本中级设计给出了明确的解释:
类X的非const成员函数中的this指针的类型是X*const.也就是说,它是一个指向非常数X的常量指针(参见Const Pointers和Pointers to Const [7,21]).因为它引用的对象不是const,所以可以修改它.类X的const成员函数中的类型是const X*const.也就是说,它是一个指向常量X的常量指针.因为它引用的对象是const,所以它不能被修改.这是const和非const成员函数之间的区别.
所以在你的代码中:
class foobar
{
public:
operator int () const;
const char* foo() const;
};
Run Code Online (Sandbox Code Playgroud)
你可以这样认为:
class foobar
{
public:
operator int (const foobar * const this) const;
const char* foo(const foobar * const this) const;
};
Run Code Online (Sandbox Code Playgroud)
我想补充以下几点。
你也可以把 它变成一个const &
和const &&
所以,
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
}
Run Code Online (Sandbox Code Playgroud)
随意改进答案。我不是专家
小智 6
这里 const 意味着在该函数中任何变量的值都不能改变
class Test{
private:
int a;
public:
void test()const{
a = 10;
}
};
Run Code Online (Sandbox Code Playgroud)
就像这个例子一样,如果您尝试更改测试函数中变量的值,您将收到错误。