在这样的声明中const的含义是什么?这个常数使我困惑。
class foobar
{
public:
operator int () const;
const char* foo() const;
};
在这样的声明中const的含义是什么?这个常数使我困惑。
class foobar
{
public:
operator int () const;
const char* foo() const;
};
当前回答
const限定符意味着可以对foobar的任何值调用这些方法。当您考虑对常量对象调用非常量方法时,就会出现不同。考虑您的foobar类型是否具有以下额外的方法声明:
class foobar {
...
const char* bar();
}
方法bar()是非常量的,只能从非常量值访问。
void func1(const foobar& fb1, foobar& fb2) {
const char* v1 = fb1.bar(); // won't compile
const char* v2 = fb2.bar(); // works
}
const背后的思想是标记不会改变类内部状态的方法。这是一个强大的概念,但实际上在C++中无法实现。与其说是保证,不如说是承诺。还有一个经常破碎且容易破碎的。
foobar& fbNonConst = const_cast<foobar&>(fb1);
其他回答
这些常量意味着如果“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_;
};
测试
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
}
阅读此处了解更多信息
const限定符意味着可以对foobar的任何值调用这些方法。当您考虑对常量对象调用非常量方法时,就会出现不同。考虑您的foobar类型是否具有以下额外的方法声明:
class foobar {
...
const char* bar();
}
方法bar()是非常量的,只能从非常量值访问。
void func1(const foobar& fb1, foobar& fb2) {
const char* v1 = fb1.bar(); // won't compile
const char* v2 = fb2.bar(); // works
}
const背后的思想是标记不会改变类内部状态的方法。这是一个强大的概念,但实际上在C++中无法实现。与其说是保证,不如说是承诺。还有一个经常破碎且容易破碎的。
foobar& fbNonConst = const_cast<foobar&>(fb1);
https://isocpp.org/wiki/faq/const-correctness#const-成员fns
什么是“常量成员函数”?检查(而不是变异)其对象的成员函数。常量成员函数由位于成员函数参数列表后面的常量后缀表示。带有常量后缀的成员函数被称为“常量成员函数”或“检查器”。没有常量后缀的会员函数称为“非常量成员函数”和“赋值函数”弗雷德班{公众:void inspect()常量;//该成员承诺不会改变*这一点void mutate();//此成员函数可能会更改*此};void userCode(Fred可更改,常量Fred不可更改){changed.inspect();//好:不更改可更改对象changed.mutate();//好:更改一个可更改的对象不可更改的.inspect();//好:不更改不可更改的对象不可更改。mutate();//错误:尝试更改不可更改的对象}试图调用不可更改的.amutate()是在编译时捕获的错误。const没有运行时空间或速度损失,您不需要编写测试用例来在运行时检查它。应使用inspect()成员函数上的尾随常量表示该方法不会更改对象的抽象(客户端可见)状态。这与表示该方法不会更改对象结构的“原始位”略有不同。C++编译器不允许采用“逐位”解释,除非它们能够解决通常无法解决的别名问题(即,可能存在一个非常量的别名,可以修改对象的状态)。这个别名问题的另一个(重要)见解是:用指向常量的指针指向对象并不能保证对象不会改变;它只是承诺对象不会通过该指针发生更改。
C++公共知识:基本中级编程中Const成员函数的含义给出了明确的解释:
类的非常量成员函数中此指针的类型X是X*常量。也就是说,它是指向非常数X的常数指针(见Const Pointers和Pointers to Const[7,21])。因为对象它所指的不是常量,可以修改。类型这在类X的常量成员函数中是常量X*const。那个是,它是指向常量X的常量指针。因为它是常量,不能修改。这就是常量和非常量成员函数之间的差异。
因此,在您的代码中:
class foobar
{
public:
operator int () const;
const char* foo() const;
};
你可以这样想:
class foobar
{
public:
operator int (const foobar * const this) const;
const char* foo(const foobar * const this) const;
};
当您在方法签名中使用const时(如您所说的:constchar*foo()const;)你告诉编译器,这个方法(这里是foo)不能改变它指向的内存。