浅谈const变量赋值报错分析
从变量到常量的赋值是合法C++的语法约定的,
如从char到constchar顺畅;
但从char**到constchar**编译器就会报错:
error:invalidconversionfrom`char**'to`constchar**'
示例:
intmain(intargc,char*argv[]) { chara='1'; constcharb=a; char*a2="12345"; constchar*b2=a2; char**a3=NULL; //constchar**b3=a3;//error char**constc3=a3;//ok char*const*d3=a3;//ok }
原因:
constchar**b3说明b3的指针可以变更,可以再指向另外一个地址;
b3和a3都是unqualified的,但b3指向的对象类型为pointertoconstchar,
a3指向的对象类型为pointertochar,两者是不相容类型,
不符合两操作数必须指向相容类型的规定,因此赋值非法。
更详细的解释详见参考资料1;
而char**constc3=a3;正确,则是因为const限制了c3指针的地址变更,即它指向了a3,就不再能变更指向其它指针了;这就限制了指针地址变更可能发生的潜在问题;
当然这时候,使用一个强制类型转换,可以解决这个编译错误:
constchar**b3=const_cast<constchar**>(a3);//ok
但转换后的代码再出现问题就很难排查了;
强制类型转换的潜在问题
看以下示例:
classFoo{ public: Foo(){ i=1; } voidmodify(){//makesomemodificationtothethisobject i=2; } voidprint()const{ cout<<"Foo_i:"<<i<<endl; } private: inti; }; //演示潜在的危险 //error:invalidconversionfrom`Foo**'to`constFoo**' ///////////////////////////////////////////////////////// intmain(intargc,char*argv[]) { constFoox; Foo*p; //constFoo**q=&p;//qnowpointstop;thisis(fortunately!)anerror constFoo**q=const_cast<constFoo**>(&p); *q=&x;//pnowpointstox p->modify();//Ouch:modifiesaconstFoo!! x.print();//print:Foo_i:2 return0; }
我们定义了一个常量的Foo,常量Foo方法打印出来的永远为1;
Foo**到constFoo**的转换报错,
通过一个强转符让编译通过,
最后的x.print()的结果是2;这样的潜在危险在正式的项目代码中就很难发现;
很难会想到一个const对象还能够变更;
以上所述就是本文的全部内容了,希望大家能够喜欢。