static_cast <typeid>(exdlvssion)

static_cast 很像 C 语言中的旧式类型转换。它能进行基础类型之间的转换,也能将带有可被单参调用的构造函数或用户自定义类型转换操作符的类型转换,还能在存有继承关系的类之间进行转换(即可将基类转换为子类,也可将子类转换为基类),还能将 non-const对象转换为 const对象(注意:反之则不行,那是const_cast的职责。)。

double d = 3.14159265;
int i = static_cast<int>(d); class A {};
class B
{
public:
B (A a) {};
};
A a;
B b = static_cast<B>(a); class CBase {};
class CDerived: public CBase {};
CBase * a = new CBase;
CDerived * b = static_cast<CDerived *>(a);
注意:static_cast 转换时并不进行运行时安全检查,所以是非安全的,很容易出问题。因此 C++ 引入 dynamic_cast 来处理安全转型。

dynamic_cast<typeid>(exdlvssion)

dynamic_cast 主要用来在继承体系中的安全向下转型。它能安全地将指向基类的指针转型为指向子类的指针或引用,并获知转型动作成功是否。如果转型失败会返回null(转型对象为指针时)或抛出异常(转型对象为引用时)。dynamic_cast 会动用运行时信息(RTTI)来进行类型安全检查,因此 dynamic_cast 存在一定的效率损失。(我曾见过属于优化代码80/20法则中的20那一部分的一段游戏代码,起初使用的是 dynamic_cast,后来被换成 static_cast 以提升效率,当然这仅是权宜之策,并非好的设计。)

class CBase { };
class CDerived: public CBase { };
CBase b;
CBase* pb;
CDerived d;
CDerived* pd;
pb = dynamic_cast<CBase*>(&d); // ok: derived-to-base
pd = dynamic_cast<CDerived*>(&b); // error: base-to-derived

上面的代码中最后一行会报如下错误 ,这是因为 dynamic_cast 只有在基类带有虚函数的情况下才允许将基类转换为子类。

class CBase
{
virtual void dummy() {}
};
class CDerived: public CBase
{
int a;
}; int main ()
{
CBase * pba = new CDerived;
CBase * pbb = new CBase;
CDerived * pd1, * pd2;
pd1 = dynamic_cast<CDerived*>(pba);
pd2 = dynamic_cast<CDerived*>(pbb);
return ;
}

结果是:上面代码中的 pd1 不为 null,而 pd2 为 null。

class BaseClass {
public:
  int m_iNum;
  virtual void foo(){}; //基类必须有虚函数。保持多台特性才能使用dynamic_cast
}; class DerivedClass: public BaseClass {
public:
  char *m_szName[];
  void bar(){};
}; BaseClass* pb = new DerivedClass();
DerivedClass *pd1 = static_cast<DerivedClass *>(pb); //子类->父类,静态类型转换,正确但不推荐
DerivedClass *pd2 = dynamic_cast<DerivedClass *>(pb); //子类->父类,动态类型转换,正确 BaseClass* pb2 = new BaseClass();
DerivedClass *pd21 = static_cast<DerivedClass *>(pb2); //父类->子类,静态类型转换,危险!访问子类m_szName成员越界
DerivedClass *pd22 = dynamic_cast<DerivedClass *>(pb2); //父类->子类,动态类型转换,安全的。结果是NULL

dynamic_cast 也可在 null 指针和指向其他类型的指针之间进行转换,也可以将指向类型的指针转换为 void 指针(基于此,我们可以获取一个对象的内存起始地址 const void * rawAddress = dynamic_cast<const void *> (this);)。

const_cast<typeid>(exdivission)

前面提到 const_cast 可去除对象的常量性(const),它还可以去除对象的易变性(volatile)。const_cast 的唯一职责就在于此,若将 const_cast 用于其他转型将会报错。

 void print (char * str)
{
cout << str << endl;
}
int main ()
{
const char * c = " http://www.cppblog.com/kesalin/";
print ( const_cast<char *> (c) );
return ;
}

reinterpret_cast<typeid>(exdivssion>

reinterpret_cast 用来执行低级转型,如将执行一个 int 的指针强转为 int。其转换结果与编译平台息息相关,不具有可移植性,因此在一般的代码中不常见到它。reinterpret_cast 常用的一个用途是转换函数指针类型,即可以将一种类型的函数指针转换为另一种类型的函数指针,但这种转换可能会导致不正确的结果。总之,reinterpret_cast 只用于底层代码,一般我们都用不到它,如果你的代码中使用到这种转型,务必明白自己在干什么。

int doSomething(){ return ; }

typedef void(*FuncPtr)();//FuncPtr is 一个指向函数的指针,该函数没有参数,返回值类型为 void

FuncPtr funcPtrArray[];//10个FuncPtrs指针的数组 让我们假设你希望(因为某些莫名其妙的原因)把一个指向下面函数的指针存入funcPtrArray数组:

funcPtrArray[] = &doSomething; // 编译错误!类型不匹配,reinterpret_cast可以让编译器以你的方法去看待它们:funcPtrArray

funcPtrArray[] = reinterpret_cast<FuncPtr>(&doSomething); //不同函数指针类型之间进行转换

c++强制类型转换(static_cast,const_cast,dynamic_cast,reinterpret_cast)的更多相关文章

  1. static_cast,const_cast,dynamic_cast,reinterpret_cast

    除非必要,尽量不要对变量进行强制转换.这是因为强制转换是存在风险的,但实际上在某种情况下,转型是必需的. 旧式C转型方式为(type)expression,即由一对小括号加上一个对象名称组成,而这种语 ...

  2. 【C++】 四种强制类型转换(static_cast 与 dynamic_cast 的区别!)

    强制类型转换 1. static_cast 2. dynamic_cast 3. const_cast 4. reinterpret_cast 5. 为什么要需要四种类型转换? 1. static_c ...

  3. c++中的强制转换static_cast、dynamic_cast、reinterpret_cast的不同用法儿

    c++中的强制转换static_cast.dynamic_cast.reinterpret_cast的不同用法儿   虽然const_cast是用来去除变量的const限定,但是static_cast ...

  4. C++提供的四种新式转换--const_cast dynamic_cast reinterpret_cast static_cast

    关于强制类型转换的问题,许多书都讨论过,写的最具体的是C++之父的<C++的设计和演化>. 最好的解决方法就是不要使用C风格的强制类型转换,而是使用标准C++的类型转换符:static_c ...

  5. static_cast、dynamic_cast reinterpret_cast

    关于强制类型转换的问题,很多书都讨论过,写的最详细的是C++ 之父的<C++ 的设计和演化>.最好的解决方法就是不要使用C风格的强制类型转换,而是使用标准C++的类型转换符:static_ ...

  6. C++强制类型转换操作符 const_cast

    const_cast也是一个强制类型转换操作符.<C++ Primer>中是这样描述它的: 1.将转换掉表达式的const性质. 2.只有使用const_cast才能将const性质性质转 ...

  7. c++强制类型转换:dynamic_cast、const_cast 、static_cast、reinterpret_cast

    c++强制类型转换:dynamic_cast.const_cast .static_cast.reinterpret_cast 博客分类: C/C++ CC++C#编程数据结构  dynamic_ca ...

  8. C++强制类型转换:static_cast、dynamic_cast、const_cast、reinterpret_cast

    1. c强制转换与c++强制转换 c语言强制类型转换主要用于基础的数据类型间的转换,语法为: (type-id)expression//转换格式1 type-id(expression)//转换格式2 ...

  9. C++里的强制类型转换符reinterpret_cast、static_cast 、dynamic_cast、const_cast 区别

    C 风格(C-style)强制转型如下: (T) exdivssion // cast exdivssion to be of type T 函数风格(Function-style)强制转型使用这样的 ...

随机推荐

  1. 学习“要件审判九步法”,正确处理五个关系 z

    学习“要件审判九步法”,正确处理五个关系 2015-06-29 07:39:07 | 来源:人民法院报第二版 | 作者:阮丹军 “要件审判九步法”,是邹碧华法官总结审判和审判管理双重经验后的心血之作, ...

  2. Quartz CronTrigger配置

    关于cron表达式(来自网络): Cron 表达式包括以下 7 个字段: 秒 分 小时 月内日期 月 周内日期 年(可选字段) 特殊字符 Cron 触发器利用一系列特殊字符,如下所示: 反斜线(/)字 ...

  3. mybatis 入门二

    1.新建一个java项目 2.加入mybatis.jar和mysql.jar 3.加mybatis的配置文件 mybatis.xml <?xml version="1.0" ...

  4. awk 两列相减

    cat http.txt  |awk -F ':' '{print($2-$3)}' 百度文库

  5. jQuery formValidator表单验证插件常见问题

    1.    如何实现一个控件,根据不同的情况,实现不同的控制? 2.    一个页面上我有几个tab页,如何实现每个Tab页上的控件单独校验? 3.    我采用的页面上文字问题的方式,点提交的时候, ...

  6. Linux(Ubuntu)下MySQL的安装与配置

    转自:http://www.2cto.com/database/201401/273423.html 在Linux下MySQL的安装,我一直觉得挺麻烦的,因为之前安装时就是由于复杂的配置导致有点晕.今 ...

  7. 在AE中通过指定中心点和半径画圆

    /// <summary>/// 通过指定的中心点.半径画圆/// </summary>/// <param name="pLayer">要画的 ...

  8. VS2010 Win32项目的源码位置设置

    在VS2010中,我们可以创建一个Win32项目用来编辑C或CPP代码,项目建好后我们向项目文件夹添加代码文件,并调试能正常运行. 有时候我们会发现项目目录下没有源文件,这种情况下,可以通过设置“输出 ...

  9. Zookeeper分布式协调服务

    1.zookeeper是一个分布式协调的服务. 2.安装zookeeper的软件的机器,我们称之为zk server 3.zk里面的角色有leader.follower.observer,注意只有一个 ...

  10. 初探接口测试框架--python系列2

    点击标题下「蓝色微信名」可快速关注 坚持的是分享,搬运的是知识,图的是大家的进步,没有收费的培训,没有虚度的吹水,喜欢就关注.转发(免费帮助更多伙伴)等来交流,想了解的知识请留言,给你带来更多价值,是 ...