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以外的新风格强制
转型来消除常量,你的代码将无法编译。