C++、类、常量和奇怪的语法
我今天在重读 c++ 入门(第 4 版)――关于成员函数和 const 引用等的部分,我想出了这个奇怪的小程序:
I was re-reading c++ primer(4th ed.) today - the section on member functions and const references etc, and I came up with this wierd little program:
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;
}
我的问题是 - 为什么 c++ 允许这样的语法?为什么我可以在声明为 const 的类中编辑普通数据成员?const的要点不就是让你不能修改值吗?
My question is - why does c++ allow syntax such as this? Why can I edit normal data members in a class when it's declared const? Isn't the POINT of const to make it so that you can't modify values?
推荐答案
我会说你标记为正确的 Tony 的答案是不正确的,Michael Burr 的答案是正确的.
I'd say the answer by Tony that you marked as correct is incorrect, and the answer by Michael Burr is correct.
为了更清楚地表达他所说的(至少对我而言):
To put what he said more clearly (for me at least):
有两个可能产生误解的地方:
There are two potential places for misunderstanding:
- 隐式 const 的工作方式
this
在构造 const 对象期间的解释方式
- The way implicit const works
- The way that
this
is interpreted during construction of a const object
<小时>
1.隐式常量
Implicit const(ConstCheater
内部的 constification 当它被制成 const
时)不会将 cc
变成 pointer-to-const
而是一个const-pointer
,也就是说当你这样做的时候:
1. Implicit Const
Implicit const (the constification internal to ConstCheater
when it is made const
) doesn't turn cc
into a pointer-to-const
but rather a const-pointer
, that is to say when you do this:
const ConstCheater cc(7);
内部来自:
ConstCheater * ccp;
...到...
ConstCheater * const ccp;
...而不是...
const ConstCheater * ccp;
这可能是意料之中的.
奇怪的是,自从 this
以来,允许将 this
传递给构造函数中的 cpp
的初始化程序,人们会认为,应该被视为 pointer-to-const
,因此不是传递给 const-pointer
的有效值.
The stranger thing is though is that this
is allowed to be passed to cpp
's initializer in the constructor since this
, one would think, should be treated as a pointer-to-const
, and thus not a valid value to pass to a const-pointer
.
也就是说人们可能期望:
That is to say one might expect:
...: ccp(this) ... // expected to fail but doesnt
失败,因为从概念上讲,您可能期望这(在某种程度上)等同于:
to fail because conceptually you might expect that this was (somewhat) equivalent to:
const ConstCheater cc(7);
const ConstCheater * const this = &cc; // const-pointer-to-const
因此你会认为:
ConstCheater * const ccp = this; //expected error!
会失败!但它不是因为显然在构造过程中,显然 this
被特殊对待,就好像它是:
would fail! But it doesn't because apparently during construction apparently this
is treated specially as if it was:
const ConstCheater * this = &cc;
因此对象在构造过程中实际上不是 const.
and thus the object is effectively not const during construction.
我不确定我是否完全理解其中的原因,但 Michael Burr 指出,提供预期行为似乎存在逻辑和技术障碍,因此该标准似乎排除了当前有些奇怪的行为.
I'm not sure I understand completely the reasoning, but Michael Burr points out there appears to be a logical and technical barrier to providing the expected behavior so the standard seems to carve out the current somewhat odd behavior.
我最近问了一个相关问题:为什么 C++ 不有一个 const 构造函数? 但到目前为止还没有真正完全理解为什么它会站不住脚的原因,尽管我认为这会给 C++ 开发人员带来负担,必须为他们的任何类定义一个笨拙的 const 构造函数'想创建 const 对象.
I recently asked a related question which was: Why does C++ not have a const constructor? but thus far haven't really understood completely the reasoning why it would be untenable, though I suppose it would place a burden on C++ developers to have to define an awkward const constructor for any class they'd like to create const object of.
相关文章