static_cast、dynamic_cast、reinterpret_cast、和const_cast

关于强制类型转换的问题,很多书都讨论过,写的最详细的是C++ 之父的《C++
的设计和演化》。最好的解决方法就是不要使用C风格的强制类型转换,而是使用标准C++的类型转换符:static_cast,
dynamic_cast。标准C++中有四个类型转换符:static_cast
dynamic_cast
reinterpret_cast

const_cast
。下面对它们一一进行介绍。

static_cast


法:static_cast
< type-id > ( expression )

该运算符把
expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:

  • 用于类层次结构中基类和子类之间指针或引用的转换。进行上行转换(把子类的指针或引用转换成基类表示)是安全
    的;进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。
  • 用于基本数据类型之间的转换,如把
    int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
  • 把空指针转换成目标类型的空指针。

  • 任何类型的表达式转换成void类型。

注意:static_cast不能转换掉expression的const、
volitale、或者__unaligned属性。

dynamic_cast


法:dynamic_cast
< type-id > ( expression )

该运算符把
expression转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void
*;如果type-id是类指针类型,那么expression也必须是一个指针,如果type-id是一个引用,那么expression也必须是一个
引用。

dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。

在类层次间进行上行转换时,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则没有这个限制。这是由于运行
时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表(关于虚函数表的概念,详细可见<Inside c++ object
model>)中,只有定义了虚函数的类才有虚函数表,没有定义虚函数的类是没有虚函数表的。

另外,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); //copile error

 D *pd2 =
dynamic_cast<D *>(pb); //pd2 is NULL

 delete pb;

}


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

reinpreter_cast


法:reinpreter_cast
<type-id> (expression)

type-id必须是一个
指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整
数转换成原类型的指针,还可以得到原先的指针值)。

该运算符的用法比较多。

const_cast

用法:const_cast
<type_id>
(expression)

该运算符用来修改类型的const或volatile属性。除了const
或volatile修饰之外, type_id和expression的类型是一样的。

常量指针被转化成非常量指针,并且仍然指向原来的
对象;常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。

Voiatile和const类试。举如下一
例:

class B{

 public:

 int m_iNum;

}

void
foo(){

const B b1;

b1.m_iNum = 100; //comile
error

B b2 = const_cast<B>(b1);

b2. m_iNum = 200;
//fine
 }

上面的代码编译时会报错,因为b1是一个常量对象,不能对它进行改变;使用const_cast把它转换成一个常量对象,就可以对它的数据成员任意改变。
注意:b1和b2是两个不同的对象。

时间: 2024-08-01 16:35:59

static_cast、dynamic_cast、reinterpret_cast、和const_cast的相关文章

static_cast,dynamic_cast,reinterpret_cast和const_cast的区别详解_C 语言

C-style cast举例: int i; double d; i = (int) d; 上面的代码就是本来为double类型的d,通过(int)d将其转换成整形值,并将该值赋给整形变量i (注意d本身的值并没有发生改变).这就是典型的c-style类型转换. 下面是一个简单的程序: 复制代码 代码如下: #include <iostream>using namespace std; int main(void){         int i;         double d = 11.2

static_cast,dynamic_cast,reinterpret_cast,const_cast的区别及用法详解_C 语言

1.static_cast对类的指针只能转换有继承关系的类.对普通的指针来说只能在void*和其他指针之间转换.它还可转换简单的类型,比如int到char等.不能提供数字到指针的转换.不能提供不同类型指针之间的转换比如int*到char*. 2.dynamic_cast提供安全的转换如果两个指针不存在继承关系转换会失败返回空指针,如果你提供一个错误的指针那样会发生内存访问异常,因为它会去比较两个类型的虚函数表.虚函数表的指针一般放在对象指针最开始的四字节中,你去访问一个错误的地址这样肯定会发生异

C++之static_cast, dynamic_cast, const_cast

转自:http://www.cnblogs.com/chio/archive/2007/07/18/822389.html 首先回顾一下C++类型转换: C++类型转换分为:隐式类型转换和显式类型转换 第1部分. 隐式类型转换 又称为"标准转换",包括以下几种情况:1) 算术转换(Arithmetic conversion) : 在混合类型的算术表达式中, 最宽的数据类型成为目标转换类型.   int ival = 3;double dval = 3.14159; ival + dva

static_cast, dynamic_cast, const_cast探讨

 首先回顾一下C++类型转换: C++类型转换分为:隐式类型转换和显式类型转换 第1部分. 隐式类型转换 何时发生隐式类型转换 在下面这些情况下,编译器会自动地转换运算对象的类型: 在大多数表达式中,比int类型小的整型值首先提升为较大的整数类型 在条件中,非布尔值转换为布尔类型 初始化过程中,初始值转换成变量的类型:在赋值语句中,右侧运算对象转换成左侧运算对象的类型 如果算术运算或关系运算的运算对象有多种类型,需要转换成同一种类型 函数调用时也会发生类型转换   又称为"标准转换",

C++中的四种类型转换_C 语言

1 引子 这篇笔记是根据StackOverflow上面的一个问题整理而成,主要内容是对C/C++当中四种类型转换操作进行举例说明.在之前其实对它们都是有所了解的,而随着自己在进行总结,并敲了一些测试示例代码进行验证之后,对它们的理解又深刻了一些. 总所周知,在C++ 当中引入了四种新的类型转换操作符:static_cast, dynamic_cast, reinterpret_cast,还有const_cast.就自己见过的一些C++代码当中,它们的使用其实并不普遍.不少程序员依然乐于去使用C-

&lt;转&gt;标准C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast、和const_cast

static_cast 用法:static_cast<type-id>(expression) 该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性.它主要有如下几种用法: ①用于类层次结构中基类和子类之间指针或引用的转换. 进行上行转换(把子类的指针或引用转换成基类表示)是安全的: 进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的. ②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum.

C++中四种类型转换 const_cast是否能改变常量

we have four specific castingoperators:dynamic_cast, reinterpret_cast, static_cast and const_cast. Their format is to follow the new type enclosed between angle-brackets (<>) and immediately after, the expression to be converted between parentheses.

C++标准转换运算符dynamic_cast

dynamic_cast <new_type> (expression) dynamic_cast运算符,应该算是四个里面最特殊的一个,因为它涉及到编译器的属性设置,而且牵扯到的面向对象的多态性跟程序运行时的状态也有关系,所以不能完全的使用传统的转换方式来替代.但是也因此它是最常用,最不可缺少的一个运算符. 与static_cast一样,dynamic_cast的转换也需要目标类型和源对象有一定的关系:继承关系. 更准确的说,dynamic_cast是用来检查两者是否有继承关系.因此该运算符实

C++常见面试题

题目: 关于C++中, 四种类型转换的关键字, 的详解, 也可以给出代码, 判断输出 或 判断哪些代码有误. 答案及范例如下: 四种关键字: const_cast, 常量性转除;dynamic_cast, 向下安全转型; reinterpret_cast, 重新解释转型; static_cast, 静态转型; 1.  const_cast, 常量性转除: 主要对变量的常量性(const)进行操作, 移除变量的常量性, 即可以被非常量指向和引用, 详见代码; 2. dynamic_cast, 向下