关闭

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

标签: C++类型转换const-cast
232人阅读 评论(0) 收藏 举报
分类:

今天看《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限定的目的绝对不是为了修改它的内容,通过这篇,想告诉大家的就是,尽量不要使用类型转换(如果必定要使用,请使用类型转换符,方便查错)

2
0
查看评论

c++ 类型转换const_cast<type id>(num);

const_cast(num);他的作用就是把const去掉,让变量可以被修改,但是他们的地址仍然是相关的. 直接说正题把.有没有遇到这样的问题, string miss(const string &str,const string &str1) {  ...
  • sinat_14854721
  • sinat_14854721
  • 2017-07-31 22:09
  • 156

【c/c++】类型转换函数(类型转换运算符重载函数)

用转换构造函数可以将一个指定类型的数据转换为类的对象。但是不能反过来将一个类的对象转换为一个其他类型的数据(例如将一个Complex类对象转换成double类型数据)。 C++提供类型转换函数(type conversion function)来解决这个问题。类型转换函数的作用是将一个类的对象转换...
  • lzm18064126848
  • lzm18064126848
  • 2016-01-04 18:09
  • 2807

static_cast,const_cast,dynamic_cast, reinterpret_cast四种类型转换区别

一 C风格显式转换和函数风格式转换     在C++中有些数据类型的转换是可以直接转换的,这种称为隐式转换。例如: double a = 12.0; int b = a;但有时编译器对于一些数据精度变小的转换会报错,幸运的是C++给我们几个简单的强...
  • hhhhh2333
  • hhhhh2333
  • 2016-11-19 01:55
  • 321

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

类型转换是一种让程序员能够暂时或永久性改变编译器对对象的解释机制。可改变对象解释方式的运算符称为类型转换运算符。 为何需要进行类型转换 通常为了实现使用不同环境的个人和厂商编写的模块能够相互调用和协作,程序员需要让编译器按照所需的方式解释数据,并成功编译和执行。一个非常经典的例子是:目前很多C++程...
  • LG1259156776
  • LG1259156776
  • 2015-07-22 15:55
  • 1123

C++的const_cast的问题

和上一篇文章一样了,还是提起一下大约一年前我来公司面试所遇到的一道题目,题目很简单:C++有多少种cast,它们的名称和功能各是什么。(我之前的文章曾经提到过,但后来我发现自己写得并不够简明)答案如下: 一共四种cast。1、static_cast,支持子类指针到父类指针的转换,并根据实际...
  • guogangj
  • guogangj
  • 2007-03-29 11:59
  • 6018

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

(转)static_cast 与reinterpret_cast static_cast 用法:static_cast ( expression ) 该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法: ①用于类层次结构中基类和...
  • ysmz4
  • ysmz4
  • 2013-12-22 23:52
  • 550

C++四种强制类型转换运算符

C++有四种强制类型转换符,分别是dynamic_cast,const_cast,static_cast,reinterpret_cast。 其中dynamic_cast与运行时类型转换密切相关,在这里我们先介绍dynamic_cast,其他三种在后面介绍。 1、dynamic_cast运...
  • jsc0218
  • jsc0218
  • 2014-03-20 00:19
  • 7674

C++类型转换运算符之const_cast<newtype>(expression)

功能:主要是在const和volatile之间的转换 Step1:const转换为volatile示例 //< Const_cast.cpp #include using namespace std; int main(int args, char* argv[]) { //<...
  • u012421852
  • u012421852
  • 2016-04-17 20:37
  • 163

c++-const_cast 使用

C++提供了四个转换运算符: const_cast (expression) static_cast (expression) reinterpret_cast (expression) dynamic_cast (expression)一、const_cast (expressio...
  • qq_30968657
  • qq_30968657
  • 2016-12-26 15:47
  • 202

C++ 转换类型运算符 通过operator关键字进行转换

C++ 转换类型运算符 通过operator关键字进行转换
  • helainthus
  • helainthus
  • 2016-05-18 19:58
  • 338
    个人资料
    • 访问:22383次
    • 积分:806
    • 等级:
    • 排名:千里之外
    • 原创:55篇
    • 转载:2篇
    • 译文:1篇
    • 评论:0条
    文章分类