C++提供了四个转换运算符
- const_cast <new_type> (expression)
- static_cast <new_type> (expression)
- reinterpret_cast <new_type> (expression)
- dynamic_cast <new_type> (expression)
它们有着相同的结构,看起来像是模板方法。这些方法就是提供给开发者用来进行指针和引用的转换的。
1、const_cast用法
const_cast是一种C++运算符,主要是用来去除复合类型中const和volatile属性(没有真正去除)。
变量本身的const属性是不能去除的,要想修改变量的值,一般是去除指针(或引用)的const属性,再进行间接修改。
用法:const_cast<type>(expression)
通过const_cast运算符,也只能将const type*转换为type*,将const type&转换为type&。
也就是说源类型和目标类型除了const属性不同,其他地方完全相同。
#include<iostream>
using namespace std;
void ConstTest1(){
const int a = ;
int *p;
p = const_cast<int*>(&a);
(*p)++;
cout<<a<<endl;
cout<<*p<<endl; }
void ConstTest2(){
int i;
cout<<"please input a integer:";
cin>>i;
const int a = i;
int &r = const_cast<int &>(a);
r++;
cout<<a<<endl;
}
int main(){
ConstTest1();
ConstTest2();
return ;
}
输出: 若输入7
则输出8
解释为什么输出8:
当常变量为 const int j =i 时,直接输出j时,编译器不能进行优化,也就是不能够直接用i代替j;(r是a的引用,r变,a会变)
当常变量为const int j =5时,直接输出j时,编译器会进行优化,也就是用文字常量5直接代替j;
2) static_cast
用法:static_cast <typeid> (expression)
说明:该运算符把expression转换为typeid类型,但没有运行时类型检查来确保转换的安全性。
用途:
a) 用于类层次结构中基类和派生类之间指针或者引用的转换。up-casting (把派生类的指针或引用转换成基类的指针或者引用表示)是安全的;down-casting(把基类指针或引用转换成子类的指针或者引用)是不安全的。
b) 用于基本数据类型之间的转换,如把int转换成char,这种转换的安全性也要由开发人员来保证。
c) 可以把空指针转换成目标类型的空指针(null pointer)。
d) 把任何类型的表达式转换成void类型。
注意: static_cast不能转换掉expression的const、volitale或者__unaligned属性。
class A
{
public:
virtual void a()
{
cout << 'a' << endl;
} virtual void b()
{
cout << 'a' << endl;
} private:
int i;
}; class B:public A
{
public:
virtual void a()
{
cout << 'b' << endl;
}
}; int main(void)
{
A *pa = new A();
B *pb = static_cast<B*>(pa); B *ppb = new B();
A *ppa = static_cast<A*>(ppb); return ;
}
3) reinterpret_cast
用法:reinterpret_cast <typeid>(expression)
说明:转换一个指针为其他类型的指针,也允许将一个指针转换为整数类型,反之亦然。这个操作符能够在非相关的类型之间进行转换。操作结果只是简单的从一个指针到别的指针的值的二进制拷贝,在类型之间指向的内容不做任何类型的检查和转换。这是一个强制转换。使用时有很大的风险,慎用之。
注意:reinterpret _cast不能转换掉expression的const、volitale或者__unaligned属性。
4)dynamic_cast
用法:dynamic_cast <typeid> (expression)
说明:该运算符把expression转换成typeid类型的对象。typeid必须是类的指针、类的引用或者void*。如果typeid是类的指针类型,那么expression也必须是指针,如果typeid是一个引用,那么expression也必须是一个引用。一般情况下,dynamic_cast用于具有多态性的类(即有虚函数的类)的类型转换。
dynamic_cast依赖于RTTI信息,其次,在转换时,dynamic_cast会检查转换的source对象是否真的可以转换成target类型,这种检查不是语法上的,而是真实情况的检查。先看RTTI相关部分,通常,许多编译器都是通过vtable找到对象的RTTI信息的,这也就意味着,如果基类没有虚方法,也就无法判断一个基类指针变量所指对象的真实类型,这时候,dynamic_cast只能用来做安全的转换,例如从派生类指针转换成基类指针。而这种转换其实并不需要dynamic_cast参与。也就是说,dynamic_cast是根据RTTI记载的信息来判断类型转换是否合法的。
用途:主要用于类层次之间的up-casting和down-casting,还可以用于类之间的交叉转换。在进行down-casting时,dynamic_cast具有类型检查的功能,比static_cast更安全。检测在运行时进行。如果被转换的指针不是一个被请求的有效完整的对象指针,返回值为NULL。当用于多态类型时,它允许任意的隐式类型转换以及相反过程。不过,与static_cast不同,在后一种情况里(注:即隐式转 换的相反过程),dynamic_cast会检查操作是否有效。也就是说,它会检查转换是否会返回一个被请求的有效的完整对象。
注意:dynamic_cast不能转换掉expression的const、volitale或者__unaligned属性。
C++提供了四个转换运算符的更多相关文章
- C++标准转换运算符const_cast
前面讲了C++继承并扩展C语言的传统类型转换方式,最后留下了一些关于指针和引用上的转换问题,没有做详细地讲述.C++相比于C是一门面向对象的语言,面向对象最大的特点之一就是具有“多态性(Polymor ...
- C++标准转换运算符
C++类型转换在实际编程中会经常使用,其实,本质上对象的类型用来解释(interpret)对象.因为,每个对象都占据一块内存空间,这块内存空间存放了一段二进制数据.通过标记该对象的类型,告诉如何看待这 ...
- 菜鸡的Java笔记 第四 - java 基础运算符
数学运算符,逻辑运算,三目运算,位运算 double d2 = 314e2; //采用科学计数法的写法,表示10的2次方.= 31400.0 代码写的越简单越好 简化运算符 代码:x=x+y 可以 ...
- C++标准转换运算符reinterpret_cast
C++标准转换运算符reinterpret_cast reinterpret_cast <new_type> (expression) reinterpret_cast运算符是用来处理无关 ...
- JavaScript(第四天)【运算符】
ECMA-262描述了一组用于操作数据值的运算符,包括一元运算符.布尔运算符.算术运算符.关系运算符.三元运算符.位运算符及赋值运算符.ECMAScript中的运算符适用于很多值,包括字符串.数值.布 ...
- C++标准转换运算符dynamic_cast
dynamic_cast <new_type> (expression) dynamic_cast运算符,应该算是四个里面最特殊的一个,因为它涉及到编译器的属性设置,而且牵扯到的面向对象的 ...
- 《挑战30天C++入门极限》C++运算符重载转换运算符
C++运算符重载转换运算符 为什么需要转换运算符? 大家知道对于内置类型的数据我们可以通过强制转换符的使用来转换数据,例如(int)2.1f;自定义类也是类型,那么自定义类的对象在很多情况下也 ...
- C++中四种转换类型的区别
一.四种转换类型比较: 类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可 ...
- 【转】C++标准转换运算符reinterpret_cast
reinterpret_cast<new_type> (expression) reinterpret_cast运算符是用来处理无关类型之间的转换:它会产生一个新的值,这个值会有与原始参数 ...
随机推荐
- PHP 学习笔记之一:thinkPHP的volist标签
Volist标签主要用于在模板中循环输出数据集或者多维数组. 属性: name : 必须,输出数据模板变量,后台提供的变量. id : 必须,是循环变量,可以随便定义,但是不能跟name相同. 举个栗 ...
- FZU 2252 Yu-Gi-Oh!(枚举+贪心)
Problem 2252 Yu-Gi-Oh! Accept: 105 Submit: 628 Time Limit: 1000 mSec Memory Limit : 32768 KB ...
- 洛谷P2178 品酒大会【后缀数组】【单调栈】
题目描述 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战 两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个奖项,吸引了众多品酒师参加. 在大会的晚餐上,调酒师 Rainb ...
- SQL Fundamentals || Single-Row Functions || 转换函数 Conversion function
SQL Fundamentals || Oracle SQL语言 SQL Fundamentals: Using Single-Row Functions to Customize Output使 ...
- Linux:file命令显示自定义文件类型
file 命令可以查看文件类型信息,原理见: 非常Linux-file命令与magic file 修改 /ect/magic 文件后,可用 file 命令显示自定义文件类型信息. man magic ...
- free 释放内存
http://www.cplusplus.com/reference/cstdlib/free/ free void free (void* ptr); Deallocate memory block ...
- DDOS hulk,rudy
HULK (HTTP Unbearable Load King) HULK HULK是另一个DOS攻击工具,这个工具使用UserAgent的伪造,来避免攻击检测,可以通过启动500线程对目标发起高频率 ...
- 应该掌握的JQuery的7个效果
一: 语法: $(selector).hide(speed,callback); $(selector).show(speed,callback); 实例 //点击隐藏 $("#hide&q ...
- Building a Space Station---poj2031(最小生成树)
题目链接:http://poj.org/problem?id=2031 n个球型的cell,如果任意两个球表面没有接触或者没有包含关系,就选择最近的表面建立通道: 所以用maps[i][j]表示i,j ...
- vue中给请求到的数据对象加属性问题
今天发现了个很奇怪的问题,我在做一个:点击列表 使点中的列表项变色的功能,而且是多个大列表项,在每个大列表项里点击切换列表项的时候不影响其他大列表项的选项. 解决思路,因为这些大列表项是请求到的数据 ...