【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 = " ...
随机推荐
- Learning JavaScript Design Patterns The Module Pattern
The Module Pattern Modules Modules are an integral piece of any robust application's architecture an ...
- MSSQLSERVER数据库- 解决不允许保存更改表结构
工具菜单----选项----Designers(设计器)----阻止保存要求重新创建表的更改 取消勾选
- iOS 开发中使用到的小技巧汇总
国庆即将来到,一个小项目也即将完成,把自己在项目中用的一些小技巧写出来,方便查找. 1,去掉分割线--动画设置透明度alpha //去掉tableView的分隔线: self.tableVie ...
- mvc:annotation-driven' must have no character or element问题
使用SpringMVC,启动tomcat报这个错误 解决办法 首先将Spring版本提升到3.1及以上 如果还不行替换xml文件头部: <?xml version="1.0" ...
- 《编程导论(Java)·2.1.3改写(override)》
<编程导论(Java)·2.1.3改写(override)>,收集override内容. 方法改写(method overriding)是指对于父类定义的一个实例方法,同意子类提供自己的实 ...
- MySQL协议分析
MySQL协议分析 标签: mysql 2015-02-27 10:22 1807人阅读 评论(1) 收藏 举报 分类: 数据库(19) 目录(?)[+] 1 交互过程 MySQL客户端与 ...
- c++ 数据持久层研究(一)
C++ORM框架自动生成代码数据库 用过Java的都知道SSH框架,特别对于数据库开发,Java领域有无数的ORM框架,供数据持久层调用,如Hibernate,iBatis(现在改名叫MyBatis ...
- 【转】cocos2d-x获取系统时间——2013-08-25 10
欢迎转载,本帖地址:http://blog.csdn.net/jinjian2009/article/details/9449585 之前使用过cocos2d-x获取系统时间,毫秒级的 long ge ...
- C#多线程编程(1):线程的启动
转:http://blog.csdn.net/zhoufoxcn/article/details/4402999 在实例化Thread的实例,需要提供一个委托,在实例化这个委托时所用到的参数是线程将来 ...
- iOS 网络编程:AFNetworking
1 简介 1.1 概念 AFNetworking网络框架并不是IOS自带的框架,而是第三方的开源框架.它是对NSURLConnection和NSURLSession API的封装,但是目前AFNetw ...