【C++】类型转换
- 引言
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++】类型转换的更多相关文章
- 为C# as 类型转换及Assembly.LoadFrom埋坑!
背景: 不久前,我发布了一个调试工具:发布:.NET开发人员必备的可视化调试工具(你值的拥有) 效果是这样的: 之后,有小部分用户反映,工具用不了(没反应或有异常)~~~ 然后,建议小部分用户换个电脑 ...
- c# 基础 object ,new操作符,类型转换
参考页面: http://www.yuanjiaocheng.net/webapi/config-webapi.html http://www.yuanjiaocheng.net/webapi/web ...
- Struts2日期类型转换
针对日期类java.util.Date进行类型转换,要求客户端使用"yyyy-MM-dd","yyyy/MM/dd"中的任意一种输入,并以"yyyy- ...
- 【.NET深呼吸】基础:自定义类型转换
照例,老周在开始吹牛之前,先讲讲小故事,这是朋友提出的建议,老TMD写技术有什么了不起的,人人都会写.后来老周想想,也确实,代码谁不会写,能写到有品位有感悟,就不容易做到.于是,老周接受了该朋友的建议 ...
- C++四种类型转换方式。
类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可以在任意类型之间转换,比 ...
- struts2类型转换
1. Struts2中的类型转换 我们知道通过HTTP提交到后台的数据,都是字符串的形式,而我们需要的数据类型当然不只字符串类型一种.所以,我们需要类型转换! 在Struts2中,类型转换的概念除了用 ...
- C++_系列自学课程_第_11_课_类型转换_《C++ Primer 第四版》
上次说了关于表达式的一些内容,说到还有一些关于数据类型转换的内容,今天我们接着八一八C++中的数据类型转换. 一.隐式类型转换 在表达式中,有些操作符可以对多种类型的操作数进行操作, 例如 + 操作符 ...
- Struts2入门(三)——数据类型转换
一.前言 笔者一直觉得,学习一个知识点,你首先要明白,这东西是什么?有什么用?这样你才能了解.好了,不说废话. 1.1.类型转换为何存在?什么是类型转换? 在MVC框架中,都是属于表示层解决方案,都需 ...
- js条件判断时隐式类型转换
Javascript 中,数字 0 为假,非0 均为真 在条件判断运算 == 中的转换规则是这样的: 如果比较的两者中有布尔值(Boolean),会把 Boolean 先转换为对应的 Number,即 ...
- JavaScript中数据类型转换总结
JavaScript中数据类型转换总结 在js中,数据类型转换分为显式数据类型转换和隐式数据类型转换. 1, 显式数据类型转换 a:转数字: 1)Number转换: 代码: var a = " ...
随机推荐
- 设置Windows的TCP/IP属性和内部网络号码
这里,以Windows XP和Windows 7版本为例. 在安装了IPX/SPX协议或TCP/IP协议的Windows计算机上可以设置计算机的内部网络号码,主要可以防止进行局域网连接时出现冲突现象. ...
- UILabel文本垂直顶部对齐的方法
也不知道为什么UILabel本身没有提供文本垂直顶部对齐的方法,真的有点晕.我们创建一个简单的UILabel来看看: [box type="info"] UILabel *myLa ...
- mybatis的$存在安全问题,为什么又不得不用?
1.mybatis的官网关于$和#的字符串替换符号区别描述如下: http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html#Parameters 上面的意 ...
- 增强Eclipse ,MyEclipse 的代码自动提示功能
一般默认情况下,Eclipse ,MyEclipse 的代码提示功能是比Microsoft Visual Studio的差很多的,主要是Eclipse ,MyEclipse本身有很多选项是默认关闭的, ...
- 导入导出封装的工具类 (一) 利用POI封装
对于导入导出各个项目中差点儿都会用到,记得在高校平台中封装过导入导出这部分今天看了看是利用JXL封装的而经理说让我用POI写写导出,这两个导入导出框架是眼下比較流程和经常使用的框架,有必要都了解一下. ...
- 表单中Readonly和Disabled的区别(转)
今天做form提交的时候,用到了disabled,form提交的时候怎么获取都是null,后来用hidden解决了这个问题,但是考虑到为什么,最后找到了原因,转载一篇文章,说明一下 原文:http:/ ...
- [Javascript] Adding Shapes to Maps with Leaflet and GeoJSON
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- linux部署tomcat
安装说明 安装环境:CentOS-6.5安装方式:源码安装 软件:apache-tomcat-6.0.45.tar.gz下载地址:http://tomcat.apache.org/download-6 ...
- hdu 1570 AC
A C Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis ...
- JS调用ashx文件传递中文参数取不到值的解决方案
引自:http://www.cnblogs.com/yinpeng186/archive/2011/09/30/2196726.html