C++ 类型转换运算符——const_cast

原创 2017年07月21日 12:02:17

今天看《Effective C++》,里面提到了关于类型转换的章节,所以就来对C++的类型转换进行一定的分析和测试吧。
C++提供了四个转换运算符:

 const_cast <new_type> (expression) 
 static_cast <new_type> (expression)
 reinterpret_cast <new_type> (expression) 
 dynamic_cast <new_type> (expression)

它们有着相同的结构,看起来有点像是模板方法。
这些方法就是提供给开发者用来进行指针和引用的类型转换的。

用const_cast来去除对象的const限定

对于一个const变量,我们不能修改它的值,这是C++强制规定的,也是这个限定符的直接表现,如果我们想修改怎么办?
以下的代码显然是不行的:

    const int Cint = 5;
    Cint =6;             //error

我们也许可以试着用指针和引用试试?

    const int Cint = 5;
//  Cint =6;             //error
    int *P_Cint = (int *)&Cint;
    *P_Cint = 6;

以上的代码并未真正修改到Cint的值,说明C++const 限定符执行的很完善,完全无机可乘

要不用const_cast试试,毕竟它主要就是负责这个的嘛:

const int Cint = 5;
const int *const PCint = &Cint;
    int * castPCint = const_cast<int*>(PCint);//解除const属性
    *castPCint = 6;
    cout << Cint << endl;// 5
    //可以看到,我们对*castPCint的修改并没有修改到Cint的值,说明C++的const的有效性
    cout << "castPCint Add: " << castPCint << endl;
    cout << "Cint Add: " << &castPCint << endl;
    //castPCint Add: 006FF7A4
    //Cint Add : 006FF78C
    //可以看到,两者的地址不一样了,但是我们的确指向了同一块地址
    //这种赋值行为被称为未定义行为(Undefined Behavior)”。所谓未定义,是说这个语句在标准C++中没有明确的规定,由编译器来决定如何处理。
    //对于未定义行为,我们所能做的所要做的就是避免出现这样的语句。对于const数据我们更要这样保证:绝对不对const数据进行重新赋值。

    //如果我们不想修改const变量的值,那我们又为什么要去const呢?
    //原因是,我们可能调用了一个参数不是const的函数,而我们要传进去的实际参数确实const的,
    //但是我们知道这个函数是不会对参数做修改的。于是我们就需要使用const_cast去除const限定,以便函数能够接受这个实际参数。

以上就是const_cast的使用方法,是不是感觉很奇怪,转换之后的const内容还是完全不能进行修改,甚至连类型转换之后的指针指向的位置都被修改了,还有我发现了一个很有意思的事情,以下代码:

    const int Cint = 5;
//  Cint =6;             //error
    int *P_Cint = (int *)&Cint;

    *P_Cint = 7;

    const int *const PCint = &Cint;
    int * castPCint = const_cast<int*>(PCint);//解除const属性
    *castPCint = 6;
    cout << Cint << endl;// 5

    cout << "PC_int Add : " << P_Cint << endl;
    cout << "castPCint Add : " << castPCint << endl;
    cout << "Cint Add : " << &castPCint << endl;
    cout << "castPCint value : " << *castPCint << endl;
    cout << "PC_int value : " << *P_Cint << endl;

输出内容如下:

5  //最原始的const value的值
PC_int Add : 0097FBE8
castPCint Add : 0097FBE8
Cint Add : 0097FBC4
castPCint value : 6
PC_int value : 6

很奇怪,为什么const_cast 和强制类型转换得到的内容地址相同呢,这就涉及到C++的未定义行为了:

所谓未定义,是说这个语句在标准C++中没有明确的规定,由编译器来决定如何处理。

位运算的左移操作也可算一种未定义行为,因为我们不确定是逻辑左移,还是算数左移。

再比如下边的语句:v[i] = i++; 也是一种未定义行为,因为我们不知道是先做自增,还是先用来找数组中的位置。

对于未定义行为,我们所能做的所要做的就是避免出现这样的语句。

对于const数据我们更要这样保证:绝对不对const数据进行重新赋值。

如果我们不想修改const变量的值,那我们又为什么要去const呢?(以下转自其他博客):

原因是,我们可能调用了一个参数不是const的函数,而我们要传进去的实际参数却是const的,但是我们知道这个函数是不会对参数做修改的。于是我们就需要使用const_cast去除const限定,以便函数能够接受这个实际参数。

#include <iostream>
using namespace std;

void Printer (int* val,string seperator = "\n")
{
    cout << val<< seperator;
}

int main(void) 
{   
    const int consatant = 20;
    //Printer(consatant);//Error: invalid conversion from 'int' to 'int*'
    Printer(const_cast<int *>(&consatant));

    return 0;
}

出现这种情况的原因,可能是我们所调用的方法是别人写的。还有一种我能想到的原因,是出现在const对象想调用自身的非const方法的时候,因为在类定义中,const也可以作为函数重载的一个标示符。

最后,还是要说一句:

使用const_cast去除const限定的目的绝对不是为了修改它的内容,通过这篇,想告诉大家的就是,尽量不要使用类型转换(如果必定要使用,请使用类型转换符,方便查错)

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

C++ 类型转换运算符——const_cast

今天看《E ffective C++》提到了关于类型转换的章节,就来对C++的类型转换进行一定的分析和测试吧。 C++提供了四个转换运算符: const_cast (expression)...

C++标准转换运算符const_cast

原文地址:http://www.cnblogs.com/ider/archive/2011/07/22/cpp_cast_operator_part2.html C++标准转换运算符...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

C++标准转换运算符const_cast

前面讲了C++继承并扩展C语言的传统类型转换方式,最后留下了一些关于指针和引用上的转换问题,没有做详细地讲述。C++相比于C是一门面向对象的语言,面向对象最大的特点之一就是具有“多态性(Polymor...

C++标准转换运算符const_cast

引用自:http://www.cnblogs.com/ider/archive/2011/07/22/cpp_cast_operator_part2.html 前面讲了C++继承并扩展C语言的传...

C++标准转换运算符const_cast

转:http://www.cnblogs.com/ider/archive/2011/07/22/cpp_cast_operator_part2.html 前面讲了C++继承并扩展C语言的传统类...

C++标准转换运算符const_cast

前面讲了C++继承并扩展C语言的传统类型转换方式,最后留下了一些关于指针和引用上的转换问题,没有做详细地讲述。C++相比于C是一门面向对象的语言,面向对象最大的特点之一就是具有“多态性(Polymor...

C++类型转换运算符: static_cast<>,reinterpret_cast<>,dynamic_cast<>, const_cast<>

(转)static_cast 与reinterpret_cast static_cast 用法:static_cast ( expression ) 该运算符把expression转换为type...
  • ysmz4
  • ysmz4
  • 2013-12-22 23:52
  • 494

C++标准转换运算符const_cast

前面讲了C++继承并扩展C语言的传统类型转换方式,最后留下了一些关于指针和引用上的转换问题,没有做详细地讲述。C++相比于C是一门面向对象的语言,面向对象最大的特点之一就是具有“多态性(Polymor...

C++标准转换运算符const_cast

C++标准转换运算符const_cast 前面讲了C++继承并扩展C语言的传统类型转换方式,最后留下了一些关于指针和引用上的转换问题,没有做详细地讲述。C++相比于C...

C++的类型转换运算符(二)——reinterpret_cast 与 const_cast

 3、reinterpret_cast reinterpret意为“重新解释” reinterpret_cast是C++中与C风格类型转换最接近的类型转换运算符。它让程序员能够将一种对象类型...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)