• 引言

  C++风格的四种类型转换方法:static_cast、dynamic_cast、reinterpret_cast、const_cast。

  欢迎来到 lovickie 的博客 http://www.cnblogs.com/lovickie

  • static_cast

  使用 static_cast 可以进行接近C风格的静态转换,但增加了安全性考虑。

double d = 3.14;
int i = static_cast<int> (d);

  欢迎来到 lovickie 的博客 http://www.cnblogs.com/lovickie

  • dynamic_cast

  上行转换(子类指针转父类指针)一般是安全的,当然必须得 public 继承才合法。下行转换(父类指针转子类指针)很可能不安全(例如当指针指向父类对象时)。

  可以采用 dynamic_cast<type> (expression) 动态转换的条件是:type为指针或引用,下行转换时基类为多态(有虚函数,从而可以在虚表中放一个类型信息指针—— dynamic_cast 的一种典型实现)。对于不安全的指针下行转换,dynamic_cast 返回 NULL。

class Dad {};
class Son: public Dad
{
public:
void func ();
}; int main ()
{
Dad d;
Son *s1 = (Son*) &d; // 编译通过
s1->func (); // 链接出错
Son *s2 = static_cast<Son*> (&d); // 编译通过
s2->func (); // 链接出错
Son *s3 = dynamic_cast<Son*> (&d); // 编译报错: Dad不是多态类型, 除非Dad中有虚函数
}
class Dad
{
virtual void func ();
};
class Son: public Dad {}; int main ()
{
Son son;
Dad *pd = dynamic_cast<Dad*> (&son); // 上行转换, ok
Dad dad;
Son *ps = dynamic_cast<Son*> (&dad); // 下行转换, ps=0 Dad *pdad = new Dad, *pson = new Son;
ps = dynamic_cast<Son*> (pdad); // 下行转换, ps=0
ps = dynamic_cast<Son*> (pson); // 下行转换, ok
}

  如上面这个例子所示,对指针下行转换时,如果失败 dynamic_cast 会返回0;而对引用下行转换时,如果失败会抛出 bad_cast 异常。

void f (Dad &dad)
{
try {
Son &son = dynamic_cast<Son&> (dad);
}
catch ( bad_cast ) {
// 异常处理
}
}

  当转换源指针或目标指针为 void * 时,dynamic_cast 总认为安全。目标指针为 void * 可以用于确定多态类型的对象的起始地址。

class A
{
virtual void func ();
}; int main ()
{
A *a = new A;
void *v = dynamic_cast<void*> (a); // 同样要求A多态
a = dynamic_cast<A*> (v);
}

  和 typeid 一样,dynamic_cast 使用了“运行时类型信息” RTTI(Run Time Type Information),某些平台可能不支持。

  欢迎来到 lovickie 的博客 http://www.cnblogs.com/lovickie

  • reinterpret_cast

  使用 reinterpret_cast<type> (expression) 可以在指针之间或指针与整数之间转换类型,同样要求 type 为指针或引用。

int *p = new int;
long i = reinterpret_cast<long> (p);
p = ; // p 不再指向 new int
p = reinterpret_cast<int*> i; // p 重新指向 new int

  欢迎来到 lovickie 的博客 http://www.cnblogs.com/lovickie

  • const_cast

  使用 const_cast 可以将常量转换为变量,去除 const 属性。

const char *str = "hello";
char *s = const_cast<char*> (str);

  在类 A 的 const 成员函数中,如果想要修改 A 的成员变量,可以先将 this 强制去除 const 属性。但当对象本身就是常量时,结果将不可预见。

class A
{
bool m;
public:
void func () const
{
A *a = const_cast<A*> (this); // 强制去除const属性
a->m = true;
}
}; int main ()
{
A a1;
const A a2;
a1.func (); // ok
a2.func (); // 无定义行为
}

  因此,令某些成员变量可被 const 成员函数修改的更好的解决方案是,将成员变量声明为 mutable,或者将这些成员变量封装到结构体指针中。

  欢迎来到 lovickie 的博客 http://www.cnblogs.com/lovickie

  • 结语

  无。

【C++】类型转换的更多相关文章

  1. 为C# as 类型转换及Assembly.LoadFrom埋坑!

    背景: 不久前,我发布了一个调试工具:发布:.NET开发人员必备的可视化调试工具(你值的拥有) 效果是这样的: 之后,有小部分用户反映,工具用不了(没反应或有异常)~~~ 然后,建议小部分用户换个电脑 ...

  2. c# 基础 object ,new操作符,类型转换

    参考页面: http://www.yuanjiaocheng.net/webapi/config-webapi.html http://www.yuanjiaocheng.net/webapi/web ...

  3. Struts2日期类型转换

    针对日期类java.util.Date进行类型转换,要求客户端使用"yyyy-MM-dd","yyyy/MM/dd"中的任意一种输入,并以"yyyy- ...

  4. 【.NET深呼吸】基础:自定义类型转换

    照例,老周在开始吹牛之前,先讲讲小故事,这是朋友提出的建议,老TMD写技术有什么了不起的,人人都会写.后来老周想想,也确实,代码谁不会写,能写到有品位有感悟,就不容易做到.于是,老周接受了该朋友的建议 ...

  5. C++四种类型转换方式。

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

  6. struts2类型转换

    1. Struts2中的类型转换 我们知道通过HTTP提交到后台的数据,都是字符串的形式,而我们需要的数据类型当然不只字符串类型一种.所以,我们需要类型转换! 在Struts2中,类型转换的概念除了用 ...

  7. C++_系列自学课程_第_11_课_类型转换_《C++ Primer 第四版》

    上次说了关于表达式的一些内容,说到还有一些关于数据类型转换的内容,今天我们接着八一八C++中的数据类型转换. 一.隐式类型转换 在表达式中,有些操作符可以对多种类型的操作数进行操作, 例如 + 操作符 ...

  8. Struts2入门(三)——数据类型转换

    一.前言 笔者一直觉得,学习一个知识点,你首先要明白,这东西是什么?有什么用?这样你才能了解.好了,不说废话. 1.1.类型转换为何存在?什么是类型转换? 在MVC框架中,都是属于表示层解决方案,都需 ...

  9. js条件判断时隐式类型转换

    Javascript 中,数字 0 为假,非0 均为真 在条件判断运算 == 中的转换规则是这样的: 如果比较的两者中有布尔值(Boolean),会把 Boolean 先转换为对应的 Number,即 ...

  10. JavaScript中数据类型转换总结

    JavaScript中数据类型转换总结 在js中,数据类型转换分为显式数据类型转换和隐式数据类型转换. 1, 显式数据类型转换 a:转数字: 1)Number转换: 代码: var a = " ...

随机推荐

  1. 部署ActiveMQ的Share File System Master-Slave

    之前在项目里用MQ是用单节点,因为业务量不大没有主从.这样风险很大,会有单点问题.新项目起来了,需要一个高可用的MQ,故研究了下AMQ的几种master-slave方式: 1.Pure Master- ...

  2. fileupload控件上传、文件下载

    常遇到上传下载的功能,这里把我习惯的用法写下来: 上传: string fileName = "";fileName = this.fu_pic.FileName;if (stri ...

  3. HDU 1518 Square

    解题思路:sum%4!=0    , max<sum/4 #include<iostream>#include<cstdio>#include<cstring> ...

  4. response对象详解

    (响应 javax.servlet.http.HttpServletResponse) 方法名 说明 addCookie 添加一个Cookie对象 addHeader 添加Http文件指定名字头信息 ...

  5. jQuery Mobile方向感应事件

    在现在的智能手机中,都有对方向变换的自动感知功能,比如当手机方向从水平方向切换到垂直方向时,则会触发该事件.在jQuery Mobile中,可以通过orientationchange事件进行绑定,并且 ...

  6. [Node.js] Creating JWTs (JSON Web Tokens) in Node

    In this lesson we will look at all of the pieces that combine together to create a JWT (j AWT) or JS ...

  7. lscpu lsblk lsscsi lspci

    [root@server1 ~]# lscpu Architecture: x86_64 CPU op-mode(s): -bit, -bit Byte Order: Little Endian CP ...

  8. Android(java)学习笔记157:使用Dexdump等工具进行反编译

    使用Dex等工具进行反编译步骤: (1)首先找到Android软件安装包中的class.dex,把APK文件改名为".zip",然后解压缩其中的class.dex文件,这是Java ...

  9. 【转】MyEclipse第一个Servlet程序

    转自:http://blog.csdn.net/wangdingqiaoit/article/details/7674367 前言 本文旨在帮助学习java web开发的人员,熟悉环境,在Win7系统 ...

  10. Linux环境下搭建Android开发环境

    最近在折腾linux.因为咱是搞安卓开发的,所以少不了需要搭建Android开发环境,就此小记,希望能给向我一样的开发者一点帮助!开干! 1.安装JDK 下载JDK包,得到的是类似于jdk-8u65- ...