在一本关于C ++(C ++ for Dummies)的书中,有一节说明如下:
int nVar = 10;
int* pVar = &nVar;
const int* pcVar = pVar; // this is legal
int* pVar2 = pcVar; // this is not
然后这本书继续解释:
作业pcVar = pVar;没关系 - 这是添加const 限制。从那以后,不允许在代码段中进行最终分配 它试图删除pcVar的常量
我的问题是为什么最后一行不合法。我不明白这是如何阻碍pcVar的“常量”。感谢。
答案 0 :(得分:3)
const int *pcVar = pVar;
int *pVar2 = pcVar;
如果pcVar
为const int *
,则表示其指向的int
可能为const
。 (不是在这种情况下,但它可能是。)因此,如果您指定pVar2
,这是一个非常量int *
,它仍然允许它指向的int
被修改。
因此,如果pcVar
实际指向const int
,并且您为其地址分配了int *
,那么int *
指针({在这种情况下,{1}}将允许您通过解除引用来修改它,这是非法的(这是违反约束,因此它会调用未定义的行为)。
答案 1 :(得分:2)
它只是说你不能从const
(至少,不是没有const
)创建一个非const_cast
指针。
const背后的想法是拥有无法意外修改的对象。通过一个简单的任务摆脱const
将是非常危险的,并允许这样的事情:
void function(int* m) {
*m = 20;
}
int main() {
const int x = 10;
//Oops! x isn't constant inside function any more, and is now 20!
function(&x);
}
另外,请查看The Definitive C++ Book and Guide List,它有很多很棒的参考资料(C ++ for dummies不能完全切割)。
答案 2 :(得分:2)
所有编译器都知道pcVar
是const int*
。也就是说,它指向const int
。仅仅因为你指出非const
int
并不重要。对于所有编译器都知道,指针值可能在某个时刻发生变化,指向真正的const
int
。因此,编译器不允许您将const int*
转换回int*
,因为它会说明它所指向的对象的const
。
有关更简单的示例,请考虑:
const int x;
const int* pc = x;
int* p = pc; // Illegal
此处,x
确实是const int
。如果您可以执行第三行,则可以通过const int
(通过执行p
)访问*pc
对象并进行修改。这很糟糕 - x
有const
是有原因的。
但是,在您给出的示例中,由于您知道原始对象是非const
,您可以使用const_cast
强制编译器信任您:
int* pVar2 = const_cast<int*>(pcVar);
请注意,仅当您知道某个该对象为非const
时才有效。
答案 3 :(得分:1)
混合const和非const是非法的。原因是,如果您告诉编译器一个位置的值是const然后使用另一个指针来修改该值,则违反了您使用第一个元素创建的const契约。
答案 4 :(得分:1)
pcVar保持不变,但pVar2指向非const,const可以添加但不会被带走。编译器不会将原始nVar视为非const,而只是尝试将const分配给非const。否则你可以绕过const并更改值。
答案 5 :(得分:1)
int * pVar = &nVar;
*pVar = 4 //is legal
const int* pcVar = pVar; // this is legal
*pcVar = 3 // this is not legal, we said the value was const thus it can not be changed
int* pVar2 = pcVar; // this is not legal because...
*pVar2 = 3 -> *pcVar = 3
答案 6 :(得分:1)
第二行 int pVar =&amp; nVar; 是错误。 g ++编译器说。 错误:从'int *'到'int'的无效转换