Focus on ACE
订阅 ace-china
电子邮件:
浏览存于
groups.google.com
上的
所有帖子
C++博客
首页
新随笔
联系
聚合
管理
64 Posts :: 3 Stories :: 22 Comments :: 0 Trackbacks
公告
欢迎大家跟我交流
gTalk: 2005119@gmail.com
我的统计
您是第
位访客
常用链接
我的随笔
我的评论
我参与的随笔
留言簿
(1)
给我留言
查看公开留言
查看私人留言
随笔分类
(74)
ACE(28)
C++&OOP(19)
Miscellaneous(23)
TAO(4)
随笔档案
(64)
2012年7月 (1)
2009年9月 (1)
2008年7月 (1)
2007年12月 (1)
2007年1月 (1)
2006年12月 (1)
2006年8月 (5)
2006年7月 (5)
2006年6月 (10)
2006年5月 (8)
2006年4月 (29)
2006年3月 (1)
文章档案
(3)
2006年5月 (1)
2006年4月 (2)
收藏夹
(4)
ACE Favorites (3)
Favorites (1)
ACE论坛
ACE Usergroups
ACE中文用户组
Huihoo ACE/TAO论坛区
网上邻居
Carrey的Blog
Huyi的Blog
Lsmodel的Blog
阿彪的Blog
编辑空间
豆豆爹的Blog
天下奇毒的Blog
我的另一个blog
小明的Blog
最新随笔
1. 欢迎访问我的新网站
2. 优先级反转
3. 如何在Windows,Visual C++下获取、配置和构建ACE及TAO?
4. 欢迎访问www.ace-tao.org/bbs
5. 使用vs2005(vc8)编译log4cpp-0.3.5rc3
6. TAO(The ACE ORB)简介
7. ACE小技巧:在ACE_Acceptor框架中,自定义服务处理器的创建
8. 小技巧: 当ACE_Svc_Handler关闭时使用的默认行为
9. 小技巧: ACE_Svc_Handler的初始化
10. 有人知道CSDN邮件列表的退订方式吗?
搜索
积分与排名
积分 - 134340
排名 - 187
最新随笔
1. 欢迎访问我的新网站
2. 优先级反转
3. 如何在Windows,Visual C++下获取、配置和构建ACE及TAO?
4. 欢迎访问www.ace-tao.org/bbs
5. 使用vs2005(vc8)编译log4cpp-0.3.5rc3
6. TAO(The ACE ORB)简介
7. ACE小技巧:在ACE_Acceptor框架中,自定义服务处理器的创建
8. 小技巧: 当ACE_Svc_Handler关闭时使用的默认行为
9. 小技巧: ACE_Svc_Handler的初始化
10. 有人知道CSDN邮件列表的退订方式吗?
最新评论
1. re: 再次获得互斥体,为什么没有死锁
@slay78
II楼 正解,linux 上不想死锁,可以用ACE_Recursive_Thread_Mutex
--hai
2. re: ACE电子书下载
看了书就下载了,怎么不提供密码啊
--peace
3. re: ACE电子书下载[未登录]
解压要密码!!!!!!!
--小明
4. re: C++编码不规范出现的错误一例的解析
sec<0 || sec>59
是不对的.应该是
sec<0 || sec>60
--mymtom
5. re: 有人知道CSDN邮件列表的退订方式吗?
直接过滤掉,Gmail就有这个功能
--HelloWorld
阅读排行榜
1. socket编程:SO_REUSEADDR例解 (转)(24322)
2. 在Visual Studio 2005下使用CPPUnit向导(5172)
3. 使用vs2005(vc8)编译log4cpp-0.3.5rc3(4153)
4. TAO(The ACE ORB)简介(3965)
5. 小技巧: ACE_Svc_Handler的初始化(3783)
评论排行榜
1. 今天喜得两本书,需要的请留言(5)
2. 将ACE事件循环与MFC UI集成的一种实现(3)
3. 巧用虚友元函数(原创)(3)
4. 再次获得互斥体,为什么没有死锁(3)
5. ACE电子书下载(2)
C++风格的类型转换的用法 (转)
C++风格的类型转换的用法
这是More Effecitve C++里的第二条对类型转换讲的很好,也很基础好懂。
Item M2:尽量使用C++风格的类型转换
仔细想想地位卑贱的类型转换功能(cast),其在程序设计中的地位就象goto语句一样令人鄙视。但是它还不是无法令人忍受,因为当在某些紧要的关头,类型转换还是必需的,这时它是一个必需品。
不过C风格的类型转换并不代表所有的类型转换功能。
一 来它们过于粗鲁,能允许你在任何类型之间进行转换。不过如果要进行更精确的类型转换,这会是一个优点。在这些类型转换中存在着巨大的不同,例如把一个指向 const对象的指针(pointer-to-const-object)转换成指向非const对象的指针(pointer-to-non -const -object)(即一个仅仅去除const的类型转换),把一个指向基类的指针转换成指向子类的指针(即完全改变对象类型)。 传统的C风格的类型转换不对上述两种转换进行区分。(这一点也不令人惊讶,因为C风格的类型转换是为C语言设计的,而不是为C++语言设计的)。
二 来C风格的类型转换在程序语句中难以识别。在语法上,类型转换由圆括号和标识符组成,而这些可以用在C++中的任何地方。这使得回答象这样一个最基本的有 关类型转换的问题变得很困难:“在这个程序中是否使用了类型转换?”。这是因为人工阅读很可能忽略了类型转换的语句,而利用象grep的工具程序也不能从 语句构成上区分出它们来。
C++通过引进四个新的类型转换操作符克服了C风格类型转换的缺点,这四个操作符是, static_cast, const_cast, dynamic_cast, 和reinterpret_cast。 在大多数情况下,对于这些操作符你只需要知道原来你习惯于这样写,
(type) expression
而现在你总应该这样写:
static_cast
<
type
>
(expression)
例如,假设你想把一个int转换成double,以便让包含int类型变量的表达式产生出浮点数值的结果。如果用C风格的类型转换,你能这样写:
int firstNumber, secondNumber;
double result = ((double)firstNumber)/secondNumber;
如果用上述新的类型转换方法,你应该这样写:
double result = static_cast
<
double
>
(firstNumber)/secondNumber;
这样的类型转换不论是对人工还是对程序都很容易识别。
static_cast 在功能上基本上与C风格的类型转换一样强大,含义也一样。它也有功能上限制。例如,你不能用static_cast象用C风格的类型转换一样把 struct转换成int类型或者把double类型转换成指针类型,另外,static_cast不能从表达式中去除const属性,因为 另一个新的类型转换操作符const_cast有这样的功能。
其它新的C++类型转换操作符被用在需要更多限制的地方。const_cast用于 类型转换掉表达式的const或volatileness属性。通过使用const_cast,你向人们和编译器强调你通过类型转换想做的只是改变一些东 西的 constness或者volatileness属性。这个含义被编译器所约束。如果你试图使用const_cast来完成修改 constness 或者volatileness属性之外的事情,你的类型转换将被拒绝。下面是一些例子:
class Widget {
};
class SpecialWidget: public Widget {
};
void update(SpecialWidget *psw);
SpecialWidget sw; // sw 是一个非const 对象。
const SpecialWidget& csw = sw; // csw 是sw的一个引用
// 它是一个const 对象
update(
&csw
); // 错误!不能传递一个const SpecialWidget* 变量
// 给一个处理SpecialWidget*类型变量的函数
update(const_cast
<
SpecialWidget
*
>
(
&csw
));
// 正确,csw的const被显示地转换掉(
// csw和sw两个变量值在update
//函数中能被更新)
update((SpecialWidget*)
&csw
);
// 同上,但用了一个更难识别
//的C风格的类型转换
Widget *pw = new SpecialWidget;
update(pw); // 错误!pw的类型是Widget*,但是
// update函数处理的是SpecialWidget*类型
update(const_cast
<
SpecialWidget
*
>
(pw));
// 错误!const_cast仅能被用在影响
// constness or volatileness的地方上。,
// 不能用在向继承子类进行类型转换。
到目前为止,const_cast最普通的用途就是转换掉对象的const属性。
第 二种特殊的类型转换符是dynamic_cast,它被用于安全地沿着类的继承关系向下进行类型转换。这就是说,你能用dynamic_cast把指向基 类的指针或引用转换成指向其派生类或其兄弟类的指针或引用,而且你能知道转换是否成功。失败的转换将返回空指针(当对指针进行类型转换时)或者抛出异常 (当对引用进行类型转换时):
Widget *pw;
update(dynamic_cast
<
SpecialWidget
*
>
(pw));
// 正确,传递给update函数一个指针
// 是指向变量类型为SpecialWidget的pw的指针
// 如果pw确实指向一个对象,
// 否则传递过去的将使空指针。
void updateViaRef(SpecialWidget& rsw);
updateViaRef(dynamic_cast
<
SpecialWidget
&
>
(*pw));
//正确。传递给updateViaRef函数
// SpecialWidget pw 指针,如果pw
// 确实指向了某个对象
// 否则将抛出异常
dynamic_casts在帮助你浏览继承层次上是有限制的。它不能被用于缺乏虚函数的类型上(参见条款M24),也不能用它来转换掉constness:
int firstNumber, secondNumber;
double result = dynamic_cast
<
double
>
(firstNumber)/secondNumber;
// 错误!没有继承关系
const SpecialWidget sw;
update(dynamic_cast
<
SpecialWidget
*
>
(
&sw
));
// 错误! dynamic_cast不能转换
// 掉const。
如你想在没有继承关系的类型中进行转换,你可能想到static_cast。如果是为了去除const,你总得用const_cast。
这四个类型转换符中的最后一个是reinterpret_cast。使用这个操作符的类型转换,其的转换结果几乎都是执行期定义(implementation-defined)。因此,使用reinterpret_casts的代码很难移植。
reinterpret_casts的最普通的用途就是在函数指针类型之间进行转换。例如,假设你有一个函数指针数组:
typedef void (*FuncPtr)(); // FuncPtr is 一个指向函数
// 的指针,该函数没有参数
// 返回值类型为void
FuncPtr funcPtrArray[10]; // funcPtrArray 是一个能容纳
// 10个FuncPtrs指针的数组
让我们假设你希望(因为某些莫名其妙的原因)把一个指向下面函数的指针存入funcPtrArray数组:
int doSomething();
你不能不经过类型转换而直接去做,因为doSomething函数对于funcPtrArray数组来说有一个错误的类型。在FuncPtrArray数组里的函数返回值是void类型,而doSomething函数返回值是int类型。
funcPtrArray[0] =
&doSomething;
// 错误!类型不匹配
reinterpret_cast可以让你迫使编译�
posted on 2006-04-16 14:21
Stone Jiang
阅读(1490)
评论(1)
编辑
收藏
引用
所属分类:
C++&OOP
、
Miscellaneous
Feedback
#
re: C++风格的类型转换的用法 (转)
2006-04-17 14:01
jzp
很多时候明白是明白,就是嫌写的麻烦。
回复
更多评论
刷新评论列表
只有注册用户
登录
后才能发表评论。
【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态!
相关文章:
在Visual Studio 2005下使用CPPUnit向导
面向对象vs基于对象
程序员的八荣八耻 -- 来源不详
关于用例的随笔
介绍一些在C++用户组中常出现的缩略语
关于用例模式的一句话评论
static_cast<>揭密 (转)
C/C++ 内存管理 Heap vs Stack
避免依赖的消息处理方式 (试译)
socket编程:SO_REUSEADDR例解 (转)
网站导航:
博客园
IT新闻
BlogJava
知识库
博问
管理
Powered by:
C++博客
Copyright © Stone Jiang