【问题标题】:C++ pointer to constant error指向常量错误的 C++ 指针
【发布时间】:2013-03-05 19:03:55
【问题描述】:

在我正在阅读的一本关于 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 限制。 sn-p 中的最终分配是不允许的,因为 它试图删除 pcVar 的 const-ness

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

【问题讨论】:

  • int pVar = &nVar 是不合法的 - 您正在将整数转换为指向整数的指针。我怀疑这是一个错字,但您可能希望更正它。
  • 该代码中没有赋值,任何引用这些初始化的书都不适合阅读。
  • 其实书上是这样的。我不知道这是否是一个错字,但如果我要纠正它,这个问题仍然有意义吗?
  • 可能是书上的错字,应该是int * pVar = &nVar;您应该更正它,以免以后混淆其他访问者
  • 哇 7 个答案在 9 分钟内

标签: c++ pointers constants


【解决方案1】:
const int *pcVar = pVar;
int *pVar2 = pcVar;

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

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

【讨论】:

    【解决方案2】:

    所有编译器都知道pcVarconst int*。也就是说,它指向const int。仅仅因为您将其指向非const int 并不重要。就编译器所知,指针值可能在某个时间点发生变化,指向真正的constint。因此,编译器不会让您从 const int* 转换回 int*,因为它会谎报它所指向的对象的 constness。

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

    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 时才有效。

    【讨论】:

      【解决方案3】:

      这只是说您不能从 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 不太适合)。

      【讨论】:

        【解决方案4】:

        混合 const 和 non-const 是非法的。原因是,如果你告诉编译器某个位置的值是 const,然后使用另一个指针来修改该值,那么你就违反了与第一个元素签订的 const 协定。

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            【解决方案6】:
            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 
            

            【讨论】:

              【解决方案7】:

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

              【讨论】:

                猜你喜欢
                • 2020-10-23
                • 1970-01-01
                • 2013-01-04
                • 1970-01-01
                • 2014-04-12
                • 2014-02-23
                • 2019-09-10
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多