C ++指向常量错误的指针

时间:2013-03-05 19:03:55

标签: c++ pointers const

在一本关于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的“常量”。感谢。

7 个答案:

答案 0 :(得分:3)

const int *pcVar = pVar;
int *pVar2 = pcVar;

如果pcVarconst 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)

所有编译器都知道pcVarconst 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对象并进行修改。这很糟糕 - xconst是有原因的。

但是,在您给出的示例中,由于您知道原始对象是非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'的无效转换