C++,Classes,Const和奇怪的语法

Seb*_*fel 7 c++ const reference class

我今天正在重读c ++入门(第4版) - 关于成员函数和const引用的部分等,我想出了这个奇怪的小程序:

using std::cout;
using std::endl;

class ConstCheater
{
public:
    ConstCheater(int avalue) : ccp(this), value(avalue) {}
    ConstCheater& getccp() const {return *ccp;}
    int value;
private:
    ConstCheater* ccp;
};

int main()
{
    const ConstCheater cc(7); //Initialize the value to 7
    cout << cc.value << endl;
    cc.getccp().value = 4;    //Now setting it to 4, even though it's const!
    cout << cc.value << endl;
    cc.value = 4;             //This is illegal
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是 - 为什么c ++允许这样的语法?为什么我可以在类声明为const时编辑类中的普通数据成员?是不是const的POINT使它不能修改值?

Ton*_*ony 6

即使getccp()是一种const方法,它也不会对你返回的引用做什么承诺.该方法本身不会修改对象,因此不会破坏规则.

如果它返回了const ConstCheater&那么那将是不同的.

如您的示例所示,const除了将其应用于对象之外,还有更多的复杂性.C++ FAQ有一个关于const正确性的部分,特别是它涵盖了你在这里强调的情况.


Cat*_*kul 2

我想说,您标记为正确的托尼的答案是不正确的,而迈克尔·伯尔的答案是正确的。

更清楚地表达他的话(至少对我来说):

有两个可能产生误解的地方:

  1. 隐式 const 的工作方式
  2. this构造 const 对象期间解释的方式

1. 隐式常量

ConstCheater隐式 const (创建时内部的 constification const)不会变成ccapointer-to-const而是 a const-pointer,也就是说,当你这样做时:

  const ConstCheater cc(7); 
Run Code Online (Sandbox Code Playgroud)

内部来自:

  ConstCheater * ccp;
Run Code Online (Sandbox Code Playgroud)

...到...

  ConstCheater * const ccp;
Run Code Online (Sandbox Code Playgroud)

...而不是...

  const ConstCheater * ccp;    
Run Code Online (Sandbox Code Playgroud)

这可能是预料之中的。

const2.对象的构建

但奇怪的是,允许在构造函数中this传递给的初始化程序,因为人们会认为 应该被视为 a ,因此不是传递给 a 的有效值。cppthispointer-to-constconst-pointer

也就是说,人们可能会期望:

 ...: ccp(this) ... // expected to fail but doesnt
Run Code Online (Sandbox Code Playgroud)

失败,因为从概念上讲,您可能认为这(在某种程度上)相当于:

 const ConstCheater         cc(7);
 const ConstCheater * const this = &cc; // const-pointer-to-const
Run Code Online (Sandbox Code Playgroud)

因此你会认为:

 ConstCheater * const ccp = this; //expected error!
Run Code Online (Sandbox Code Playgroud)

会失败的!但事实并非如此,因为显然在施工过程中显然this被特殊对待,好像它是:

 const ConstCheater * this = &cc; 
Run Code Online (Sandbox Code Playgroud)

因此该对象在构造过程中实际上不是 const。

我不确定我完全理解其中的推理,但迈克尔·伯尔指出,提供预期行为似乎存在逻辑和技术障碍,因此该标准似乎排除了当前有些奇怪的行为。

我最近问了一个相关的问题:为什么 C++ 没有 const 构造函数?但到目前为止,还没有真正完全理解为什么它站不住脚,尽管我认为这会给 C++ 开发人员带来负担,因为他们必须为他们想要创建 const 对象的任何类定义一个尴尬的 const 构造函数。