2

在我正在阅读的一本关于 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 的 const-ness

我的问题是为什么最后一行不是“合法的”。我不明白这如何阻碍 pcVar 的“常量性”。谢谢。

4

7 回答 7

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

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

因此,如果pcVar 实际上指向 a const int,并且您将 a 分配int *给它的地址,那么该int *指针(pVar2在这种情况下)将允许您通过取消引用来修改它,这是非法的(这是违反约束的,因此它会调用未定义的行为)。

于 2013-03-05T19:09:20.153 回答
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 并不完全适合)。

于 2013-03-05T19:08:01.840 回答
2

编译器只知道这pcVar是一个const int*. 也就是说,它指向一个const int. 仅仅因为你把它指向一个非const int无关紧要的。就编译器所知,指针值可能会在某个时间点更改为真正的const int. 因此,编译器不会让您从 a 转换为 a const int*int*因为它会谎报const它所指向的对象的性质。

举一个更简单的例子,考虑:

const int x;
const int* pc = x;
int* p = pc; // Illegal

在这里,x确实是一个const int。如果您可以执行第三行,则可以通过(通过执行)访问该const int对象并对其进行修改。那会很糟糕——是有原因的。p*pcxconst

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

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

请注意,这仅在您确定该对象是非. 时才有效const

于 2013-03-05T19:08:46.080 回答
1

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

于 2013-03-05T19:07:24.123 回答
1

pcVar 保持不变,但 pVar2 指向一个非常量,可以添加但不能删除 const。编译器不会将原始 nVar 视为非常量,而只是尝试将 const 分配给非常量。否则,您可以绕过 const 并更改值。

于 2013-03-05T19:08:12.923 回答
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 
于 2013-03-05T19:10:42.287 回答
1

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

于 2013-03-05T19:11:33.147 回答