我阅读了有关为什么C ++没有const构造函数的问题。
我仍然很困惑为什么该程序可以编译。我试图对这个问题发表自己的看法,但我不知道为什么要删除它。所以我不得不再次问这个问题。
这是程序
class Cheater
{
public:
Cheater(int avalue) :
value(avalue),
cheaterPtr(this) //conceptually odd legality in const Cheater ctor
{}
Cheater& getCheaterPtr() const {return *cheaterPtr;}
int value;
private:
Cheater * cheaterPtr;
};
int main()
{
const Cheater cheater(7); //Initialize the value to 7
// cheater.value = 4; //good, illegal
cheater.getCheaterPtr().value = 4; //oops, legal
return 0;
}
我的困惑是:
const Cheater cheater(7)
在其构造函数中创建一个const对象作弊者
Cheater(int avalue) :
value(avalue),
cheaterPtr(this) //conceptually odd legality in const Cheater ctor
{}
'this'指针用于初始化cheaterPtr
。
我认为这是不对的。cheater
是一个const对象,其指针应类似于:const Cheater* const this;
这意味着它本身的指针和该指针所指向的对象都应为const,我们既不能更改指针的值也不能修改指针所指向的对象。
但是对象cheater
的cheaterPtr
成员就像Cheater* const cheaterPtr
。这意味着指针是const,但是它指向的对象可以是非const。
众所周知,指针到常量到指针到非常量的转换是不允许的:
int i = 0;
const int* ptrToConst = &i;
int * const constPtr = ptrToConst; // illegal. invalid conversion from 'const int*' to 'int*'
初始化列表中如何允许从指针到常量到指针到非常量的转换?到底发生了什么?
这是我尝试提供给原始帖子的构造函数中有关“ constness”的描述:
“与其他成员函数不同,构造函数可能不会声明为const。当我们创建类类型的const对象时,直到构造函数完成对象的初始化之后,该对象才会假定其'constness'。因此,构造函数可以写入const在施工过程中的物体。”
--C ++ Primer(第5版)P262 7.1.4构造函数
您的假设是不正确的。一次带他们一个,第一个代码注释。
class Cheater
{
public:
Cheater(int avalue) :
value(avalue),
cheaterPtr(this) // NOTE: perfectly legal, as *this is non-const
// in the construction context.
{}
// NOTE: method is viable as const. it makes no modifications
// to any members, invokes no non-const member functions, and
// makes no attempt to pass *this as a non-const parameter. the
// code neither knows, nor cares whether `cheaterPtr`points to
// *this or not.
Cheater& getCheaterPtr() const {return *cheaterPtr;}
int value;
private:
Cheater * cheaterPtr; // NOTE: member pointer is non-const.
};
int main()
{
// NOTE: perfectly ok. we're creating a const Cheater object
// which means we cannot fire non-const members or pass it
// by reference or address as a non-const parameter to anything.
const Cheater cheater(7);
// NOTE: completely lega. Invoking a const-method on a const
// object. That it returns a non-const reference is irrelevant
// to the const-ness of the object and member function.
cheater.getCheaterPtr().value = 4;
return 0;
}
你说:
我认为这是不对的。作弊者是一个const对象,其指针应类似于:
const Cheater* const this
cheater
正在 const
建设中。在构造过程中,它必须是非常量的。此外,构造函数不(也无法)知道调用方已指示对象为const
。它所知道的只是构造对象的时间,这就是它的作用。此外,施工后&cheater
为const Cheater *
。const
在这种情况下,将实际的指针设为var本身也是完全不适用的。
接着...
...对象作弊者的cheaterPtr成员类似于
Cheater* const cheaterPtr;
实际上,这是一种非常准确的描述方式。因为cheater
是const
其成员是为好,这意味着cheaterPtr
构件const
; 不是它所指向的。您无法更改指针值,但是由于它不是指向const对象的指针,因此您可以自由地使用该指针来修改其指向的对象,在这种情况下恰好是this
。
如果你想既指针和指向的对象为const您已经对子级声明它const Cheater *cheaterPtr;
的成员列表。(顺便说一句,顺便说一句,它只会通过getCheaterPointer()
无效命令使该可变操作生效。它也必须返回a const Cheater*
,这意味着分配当然会失败。
简而言之,此代码完全有效。什么你希望看到(的建设意识呼叫者常量性)不是语言的一部分,而事实上,如果你想你的构造有纬度...好,它不能是结构。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句