使用const_cast丢弃constness

时间:2015-08-18 10:52:36

标签: c++ const-char

没有。这个问题不重复 When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?

这里提出的问题与描述为重复的链接没有相似之处。

第一个问题: 我在下面使用const_cast两种情况。其中一个有效。另一个没有。

1。 int * const //工作。

在此语法中,变量指向的地址无法更改。所以我使用了const_cast,如下所示:

`
int j=3;
int *k=&j;
int *m=&j;
int* const i=k; 
const_cast<int*>(i)=m; //OK: since i=m would not work so cast is necessary`

2。 const int * //不起作用。

可以更改指向的地址,但不能更改该值(尽管可以通过使变量指向不同的地址来更改)。我正在使用的const_cast似乎不起作用:

`
int j=9;
int *k=&j;
const int* i1=0;
i1=k; //OK
//*i1=10;//ERROR.`

所以我尝试通过各种方式进行类型转换,但没有任何作用:

const_cast<int*>(i1)=10;
const_cast<int*>(*i1)=l;
*i1=const_cast<int>(l);
*i1=const_cast<int*>(10);

第二个问题: 所有演员阵容是否仅适用于指针和参考? 以下示例在图片中没有指针或引用的情况下无效吗?

const int a=9;
int b=4;
const_cast<int>(a)=b; //cannot convert from 'int' to 'int'. why is compiler
                      //trying to convert from int to int anyways or fails         
                      //when both the types are same.

2 个答案:

答案 0 :(得分:3)

const_cast适用于表达式,而非对象,本身也是表达式

§5.2.11[expr.const.cast] / p1:

  

表达式const_cast<T>(v)的结果是T类型。如果T是对象类型的左值引用,则   结果是左值;如果T是对象类型的右值引用,则结果为xvalue;否则,结果   是一个prvalue和左值到右值(4.1),数组到指针(4.2)和函数到指针(4.3)标准   对表达式v

执行转换
  1. const_cast<int*>(i)=m;
  2. 此调用无效,因为作业的左侧有 prvalue 值类别,而int* prvalue不支持作业。正确的语法是const_cast<int*&>(i)=m;,但由于示例中的i被声明为const,它将调用未定义的行为

    1. const_cast<int*>(*i1)=l;
    2. 取消引用类型int*的指针会创建一个左值value-category的表达式,并且因为强制转换表达式位于赋值的左侧,所以它应该是一个强制转换为左值引用类型,即{ {1}}(前提是const_cast<int&>(*i1)=10;点未被声明为i1)。

      1. const
      2. const_cast<int>(a)=b;部分本身是有效的,特别是您可以将const_cast应用于表示不是引用类型的指针类型的对象的表达式。但由于它位于分配的左侧,因此无法编译。即使您将其更改为const_cast<int>(a),也会触发未定义的行为,因为const_cast<int&>(a)=b;被声明为a

        §7.1.6.1[dcl.type.cv] / p4:

          

        除了可以修改声明为mutable(7.1.1)的任何类成员之外,任何修改const的尝试都是如此   对象在其生命周期(3.8)中导致未定义的行为。

答案 1 :(得分:2)

第一个答案:在您的示例中,您试图强制编译器执行可以像这样解释的内容

const_cast<int*>(i1)=10; //int* = int: assign address to pointer
const_cast<int*>(*i1)=l; //const_cast<int*>(int): cast the value under pointer to pointer
*i1=const_cast<int>(l); //const_casting from const values is forbidden
*i1=const_cast<int*>(10); //10 is an rvalue

你真正想做的是取消引用非const的指针。这就是你需要这样做的原因:

int j = 9;
int *k = &j;
const int* i1 = 0;
i1 = k;
*(const_cast<int*>(i1)) = 10;

相当于

int j = 9;
int *k = &j;
const int* i1 = 0;
i1 = k;
int* temp = const_cast<int*>(i1); //you get rid of 'const'...
*temp = 10; //...and now you assign value as you wanted to - this operation became available

第二个答案:禁止使用const_cast const值,因为它会导致未定义的行为。您只能从指针或引用中删除指向最终不是const的指针的constness,只有指针不允许您修改其值。

this答案中对此问题进行了详尽描述。