首页 > 编程 > C++ > 正文

浅谈const变量赋值报错分析

2020-05-23 14:19:27
字体:
来源:转载
供稿:网友
在类中 只有静态变量能赋值 如果你不赋值 编译器会认为你这个变量根本没用 不能被修改 又没有初始值 两个办法 在构造函数的初始化列表赋值 或者在const前面加一个static
 

从变量到常量的赋值是合法C++的语法约定的, 

如从char 到const char顺畅; 
但从char **到 const char **编译器就会报错:

 

复制代码代码如下:

error: invalid conversion from `char**' to `const char**'

 

示例:
 

  1. int main(int argc, char *argv[]) 
  2.   char a = '1'
  3.   const char b = a; 
  4.  
  5.   char * a2 = "12345"
  6.   const char * b2 = a2; 
  7.  
  8.   char** a3 = NULL; 
  9.  
  10.   //const char** b3 = a3; //error 
  11.    char** const c3 = a3; //ok 
  12.    charconst * d3 = a3; //ok 
?

原因: 

const char** b3 说明 b3的指针可以变更,可以再指向另外一个地址; 
b3和a3都是unqualified的,但b3指向的对象类型为pointer to const char, 
a3指向的对象类型为 pointer to char,两者是不相容类型, 
不符合两操作数必须指向相容类型的规定,因此赋值非法。 
更详细的解释详见参考资料1;

而char** const c3 = a3;正确,则是因为const限制了c3指针的地址变更,即它指向了a3,就不再能变更指向其它指针了;这就限制了指针地址变更可能发生的潜在问题;

当然这时候,使用一个强制类型转换,可以解决这个编译错误:

 

复制代码代码如下:

    const char** b3 = const_cast<const char**>(a3); // ok

 

但转换后的代码再出现问题就很难排查了;

强制类型转换的潜在问题

看以下示例:
 

  1. class Foo { 
  2. public
  3.  Foo(){ 
  4.    i = 1; 
  5.  } 
  6.  void modify(){// make some modification to the this object 
  7.    i = 2; 
  8.  }  
  9.  void print() const { 
  10.    cout << "Foo_i:" << i << endl; 
  11.  } 
  12. private
  13.  int i; 
  14. }; 
  15.  
  16. //演示潜在的危险   
  17. //error: invalid conversion from `Foo**' to `const Foo**' 
  18. ///////////////////////////////////////////////////////// 
  19. int main(int argc, char *argv[]) 
  20.   const Foo x; 
  21.   Foo* p; 
  22.  
  23.   //const Foo ** q = &p; //q now points to p; this is (fortunately!) an error 
  24.   const Foo ** q = const_cast<const Foo **>(&p);  
  25.   *q = &x; // p now points to x 
  26.   p->modify(); // Ouch: modifies a const Foo!!  
  27.   x.print(); // print: Foo_i:2 
  28.   return 0; 
?

我们定义了一个常量的Foo,常量Foo方法打印出来的永远为1; 

Foo**到const Foo **的转换报错, 

通过一个强转符让编译通过, 

最后的x.print()的结果是2;这样的潜在危险在正式的项目代码中就很难发现; 

很难会想到一个const对象还能够变更;

以上所述就是本文的全部内容了,希望大家能够喜欢。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表