C++中四种类型转换符的总结

一、reinterpret_cast
用法:reinpreter_cast<type-id> (expression)
    reinterpret_cast操作符修改了操作数类型,但仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换,即二进制值没有变。例如:

int n=9; 
double d= reinterpret_cast< double > (n); 

在进行计算以后, d 包含无用值. 这是因为 reinterpret_cast 仅仅是复制 n 的比特位到 d, 没有进行必要的分析。 因此, 需要谨慎使用 reinterpret_cast, 只有当需要转化2个具有相同内存布局的对象时才使用reinterpret_cast. 
二、static_cast
用法:static_cast < type-id > ( expression ) 
该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:
 ①用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。 
    进行上行转换(把派生类的指针或引用转换成基类表示)是安全的; 
    进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。 
②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。这种用法等同于C中通常的加括号转换操作。 
③把空指针转换成目标类型的空指针。 
④把任何类型的表达式转换成void类型。 
    注意:static_cast不能转换掉expression的const、volitale、或者__unaligned属性。 
三、const_cast 
用法:const_cast< type-id > (exdivssion) 
该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和exdivssion的类型是一样的。 
常量指针被转化成非常量指针,并且仍然指向原来的对象; 
常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。 
下面举例说明:

lass B{
public:
  int m_iNum;
}
void foo(){

const B* b1(new B);
 b1->m_iNum = 3;     //comile error
 B* b2 = const_cast<B*>(b1);
 b2->m_iNum = 3;

}

上面的代码编译时会报错,因为b1是一个指向常对象的指针,不能对它进行改变;使用const_cast把它转换一下,去掉其常量属性,就可以对它的数据成员任意改变。
这个例子是将指向常对象的指针中的const属性去掉,const_cast还可以将指向对象的常指针中的const属性去掉。

四、dynamic_cast 
用法:dynamic_cast < type-id > ( exdivssion ) 
该运算符把exdivssion转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void *; 
如果type-id是类指针类型,那么exdivssion也必须是一个指针,如果type-id是一个引用,那么exdivssion也必须是一个引用。 只有dynamic_cast这种转换并非在编译时,而是在运行时,动态的。其它均在编译时进行。

dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。 
1)在类层次间进行上行转换时, dynamic_cast和static_cast的效果是一样的; 
     在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。

class B{
public:
int m_iNum;
virtual void foo();
};
class D:public B{
public:
char *m_szName[100];
};
void func(B *pb){
D *pd1 = static_cast<D *>(pb);
D *pd2 = dynamic_cast<D *>((pb);
}

在上面的代码段中,如果pb指向一个D类型的对象,pd1和pd2是一样的,并且对这两个指针执行D类型的任何操作都是安全的; 但是,如果pb指向的是一个B类型的对象,那么pd1将是一个指向该对象的指针,对它进行D类型的操作将是不安全的(如访问m_szName), 而pd2将是一个空指针。

另外要注意:B要有虚函数,否则会编译出错;static_cast则没有这个限制。 这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表中,只有定义了虚函数的类才有虚函数表, 没有定义虚函数的类是没有虚函数表的。

2)dynamic_cast还支持交叉转换(cross cast)。如下代码所示。

class A{
public:
int m_iNum;
virtual void f(){}
};
class B:public A{
};
class D:public A{
};
void foo(){
B *pb = new B;
pb->m_iNum = 100;
D *pd1 = static_cast<D *>((pb); //compile error
D *pd2 = dynamic_cast<D *>((pb); //pd2 is NULL
delete pb;
}

在函数foo中,使用static_cast进行转换是不被允许的, 将在编译时出错;而使用 dynamic_cast的转换则是允许的,结果是空指针。

总结:

  • reinterpret_cast 将一个类型指针转换为另一个类型指针
  • const_cast    用于去除指针变量的常属性,将它转换为一个对应指针类型的普通变量,反过来也可以将一个非常量指针转换为一个常量指针变量
  • static_cast    用于转换基本类型和具有继承关系的类新之间转换,不太用于指针类型的之间的转换
  • dynamic_cast    只能在继承类对象的指针之间或引用之间进行类型转换

[转]C++中四种类型转换符的总结的更多相关文章

  1. C++中四种类型转换以及const_cast是否能改变常量的问题

    we have four specific casting operators:dynamic_cast, reinterpret_cast, static_cast and const_cast. ...

  2. c++ --> c++中四种类型转换方式

    c++中四种类型转换方式   c风格转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少缺点, 1)它可以在任意类型之间转换,比如你可以把一个指向const对象的指针转换成指向 ...

  3. C++中四种类型转换方式

    类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可以在任意类型之间转换,比 ...

  4. 聊聊 C++ 中的四种类型转换符

    一:背景 在玩 C 的时候,经常会用 void* 来指向一段内存地址开端,然后再将其强转成尺度更小的 char* 或 int* 来丈量一段内存,参考如下代码: int main() { void* p ...

  5. C++中四种类型转换方式(ynamic_cast,const_cast,static_cast,reinterpret_cast)

    Q:什么是C风格转换?什么是static_cast, dynamic_cast 以及 reinterpret_cast?区别是什么?为什么要注意? A:转换的含义是通过改变一个变量的类型为别的类型从而 ...

  6. QL Server 中四种匹配符的含义

    SQL中我们会见到很多的匹配符,下面解释一下 % 代表零个或者多个任意字符 _ 代表一个任意字符 [] 指定范围内的任意单个字符 [^] 不在指定范围内的任意单个字符 带有匹配符的字符串必须使用引号引 ...

  7. java中四种修饰符(private、default、protected、public)的访问权限

    权限如下: no. 范围 private default protected public 1 同一包下的同一个类 √ √ √ √ 2 同一包下的不同类 × √ √ √ 3 不同包下的子类 × × √ ...

  8. C++中四种强制类型转换区别详解

    C++即支持C风格的类型转换,又有自己风格的类型转换.C风格的转换格式很简单,但是有不少缺点的: 1.转换太过随意,可以在任意类型之间转换.你可以把一个指向const对象的指针转换成指向非const对 ...

  9. 【C++】类型转换简述:四种类型转换方式的说明及应用

    本文主要简述在C++中四种类型转换的方式:static_cast.reniterpret_cast.const_cast和dynamic_cast. 在介绍C++类型转换方式之前,我们先来看看C语言的 ...

随机推荐

  1. 为你的Visual Studio单独设置代理服务器

    http://blog.sina.com.cn/s/blog_58c506600101tycn.html 最近,因为国内访问Visual Studio Online(微软的免费代码托管服务,以前叫Te ...

  2. Semantic ui 学习笔记 持续更新

    这个semantic 更新版本好快~ 首先是代码的标识<code></code> 具体样式就是红框这样的 圈起来代码感觉不错 不过要在semantic.css里在加上如下样式~ ...

  3. redis+Keepalived实现Redis主从复制

    redis+Keepalived实现Redis主从复制: 环境:CentOs6.5Master: 10.10.10.203Slave:   10.10.10.204Virtural IP Addres ...

  4. Effective Objective-C 2.0 — 第13条:用“方法调配 技术” 调试 “黑盒方法”

    自己理解是调配了方法 在运行期,可以向类中新增或替换选择子所对应的方法实现. 使用另一份实现来替换原有的方法实现,这道工序叫做“方法调配”,开发者常用此技术向原有实现中添加新功能. 一般来说,只有调试 ...

  5. python mysql

    mysql Linux 安装mysql: apt-get install mysql-server 安装python-mysql模块:apt-get install python-mysqldb Wi ...

  6. 关于MySQL的SLEEP(N)函数

    都知道通过在MySQL中执行select sleep(N)可以让此语句运行N秒钟: ? 1 2 3 4 5 6 7 mysql> select sleep(1); +----------+ | ...

  7. SandcastleBuilder-生成帮助文档的时候报错...

    错误1: SHFB: Error BE0043: Unexpected error detected in last build step. See output above for details. ...

  8. codevs4096 删数问题

    题目描述 Description 键盘输入一个高精度的正整数N,去掉其中任意S个数字后剩下的数字按原左右次序将组成一个新的正整数.编程对给定的N 和S,寻找一种方案使得剩下的数字组成的新数最小. 输入 ...

  9. WP8.1下 Cortana语音命令 VCD文件 设计

    Windows Phone8.1下的Cortana,可以通过语音的方式,打开.设置应用,进行页面跳转.执行任务. 我们先要创建VCD(VoiceCommand.xml)文件 <?xml vers ...

  10. 读取XML文件

    首先要确定好XML文件的位置,最好是放在程序的debug文件中,放在其他地方也可以,要写上绝对路径 using System; using System.Collections.Generic; us ...