浅谈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对象还能够变更;
以上所述就是本文的全部内容了,希望大家能够喜欢。