繁体   English   中英

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

[英]C++ pointer to constant error

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

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

如果pcVarconst int * ,那意味着它指向的int可能是const (它不是在这种情况下,但它可能是。)因此,如果你分配pVar2 ,这是一个非const int * ,它仍然允许它指向的int被修改。

因此,如果pcVar 实际上指向了一个const int ,并且为它的地址分配了一个int * ,那么int *指针(在这种情况下是pVar2 )将允许你通过解除引用来修改它,这是非法的(这是一个约束违规,所以它调用未定义的行为)。

它只是说,你不能创建一个非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并没有完全切入)。

所有编译器都知道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 如果您可以执行第三行,则可以通过p (通过执行*pc )访问const int对象并进行修改。 那会很糟糕 - xconst的原因。

但是,在您给出的示例中,由于您知道原始对象是非const ,因此可以使用const_cast强制编译器信任您:

int* pVar2 = const_cast<int*>(pcVar); 

请注意,这只是如果你肯定知道该对象是非有效的const

混合const和非const是非法的。 原因是,如果您告诉编译器一个位置的值是const然后使用另一个指针来修改该值,则违反了您使用第一个元素创建的const契约。

pcVar保持不变,但pVar2指向非const,const可以添加但不会被带走。 编译器不会将原始nVar视为非const,而只是尝试将const分配给非const。 否则你可以绕过const并改变值。

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 

第二行int pVar =&nVar; 是错误。 g ++编译器说。 错误:从'int *'到'int'的无效转换

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM