您的位置:首页 > 编程语言 > C语言/C++

剑指offer 2.2 - C++ 类型转换相关的关键字

2014-08-10 10:25 211 查看
1、在C++中,有哪四种与类型转换相关的关键字?
C风格(C-style)强制转型:
(T)expression // cast expression to be of type T

函数风格(Function-style)强制转型使用这样的语法:
T(expression) // cast expression to be of type T


C++提供了4种强制转换形式:
1) const_cast(expression):
一般用于强制消除对象的常量性。他是唯一能做到这一点的C++风格的强制转换
=================
这个转换类型操纵传递对象的const属性,或者是设置或者是移除:
class C{};
const C *a = new C;
C *b = const_cast<C*>(a);
const_cast也能改变一个类型的volatile qualifier

2) dynamic_cast(expression):
主要用于执行“安全的向下转型(safe downcasting)”,也就是说,要确定一个对象是否是一个继承体系中的一个特定类型。
他是唯一不能用旧风格语法执行的强制转型,也是唯一可能有重大运行时代价的强制转型。
==================
只用于对象的指针和引用。当用于多态类型时,它允许任意的隐式类型转换以及相反过程。不过,与static_cast不同,在后一种情况里(注:即隐式转换的相反过程),dynamic_cast会检查操作是否有效。也就是说,他会检查转换是否会返回一个被请求的有效的完整对象。
检查在运行时进程。如果被转换的指针不是一个被请求的有效完整的对象指针,返回值为NULL
class Base{virtual dummy() {}; };
class Derived: public Base{} ;
Base *b1 = new Derived;
Base *b2 = new Base;
Derived *d1 = dynamic_cast<Derived *>(b1); // success
Derived *d2 = dynamic_cast<Derived *>(b2); // fails: return NULL

================
如果一个引用类型执行了类型转换被且这个转换是不可能的,一个bad_cast的异常类型被跑出:

class Base{virtual dummy() {}; };
class Derived: public Base{} ;
Base *b1 = new Derived;
Base *b2 = new Base;
Derived *d1 = dynamic_cast<Derived& *>(b1); // succeeds
Derived *d2 = dynamic_cast<Derived& *>(b2); // fails: exception thrown


3) reinterpret_cast(expression):

用于底层的强制转型,导致实现依赖(implementation-dependent)(就是说,不可移植)的结果,例如,将一个指针转型
为一个整数。这样的强制转型在底层以外应该极为罕见。
==================
转换一个指针为其他类型的指针。他也许允许从一个指针转换为整数类型。反之亦然。
能够在非相关的类型之间转换。操作结果只是简单的从一个指针指到别的指针的二进制拷贝。在类型之间指向的内容不作任何类型的检查和转换。
如果情况是从一个指针到整形的拷贝,内容的解释是系统相关的,所以任何的实现都不是方便的。一个转换到足够大的整形能够包含它的指针是能够转换回有效的指针的。
class A {};
class B{};
A *a = new A;
B *b = reinterpret_cast<B*>(a);

就像传统的类型转换一样对待所有的指针的类型转换。

4) static_cast(expression):
可以被用于强制隐形转换(例如,non-const对象转为const对象,int转型为double等)它还可以用于很多这样的反向转换(例如,void *指针转型为有类型指针,基类指针转型为派生类指针),但是他不能将一个const对象转型为non-const,它最接近于C-Style的转换。
=================
允许执行任意的隐式转换和相反转换动作。
应用到类的指针上,意思是它允许子类类型的指针转换为父类型的指针(这是一种有效的隐式转换),同时,也能够执行相反动作:转换父类为他的子类。
这在最后的例子里,被转换的父类没有被检查是否与目的类型相一致。
class Base{};
class Derived: public Base{};
Derived *b = static_cast<Derived*>(a);

除了操作类型指针,也能够执行类型定义的显示的转换,以及基础类型之间的标准转换:
double d = 3.14159265;
int i = static_cast<int> d;
=============================
旧风格的强制转型依然合法,但新的形势更可取。首先,在代码中他们更容易识别,这样简化了在代码中寻找类型系统被破坏的地方的过程。
第二,更精确地指定每一个强制转型的目的,使得编译器诊断使用错误成为可能。例如,如果你试图使用一个const_cast以外的新风格强制
转型来消除常量,你的代码将无法编译。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: