c++中引入新的类型转换的原因:这是因为新的类型转换控制符可以很好的控制类型转换的过程,允许控制各种类型不同的转换.还有一点好处是C++的类型转换控制符能告诉程序员或读者我们这个转换的目的是什么,我们只要看一下代码的类型转换控制符,就能明白我们想要达到什么样的目的.
ANSI-C++ 标准定义了4种新的类型转换操作符: reinterpret_cast, static_cast, dynamic_cast 和 const_cast。所有这些操作符都是同样的使用格式:
reinterpret_cast <new_type> (expression)
dynamic_cast <new_type> (expression)
static_cast <new_type> (expression)
const_cast <new_type> (expression)
//new_type 是要转换成的目标类型,expression 是要被转换的内容。
《一》reinterpret_cast 重解释类型转换
reinterpret_cast 可以将一个指针转换为任意其它类型的指针。它也可以用来将一个指针转换为一个整型,或反之亦然。
它有着和C风格强制类型转换同样的功能;它可以转化任何的内置数据类型为其他的类型, 同时它也可以把任何类型的指针转化为其他的类型;它的机理是对二进制数据进行重新的解释,不会改变原来的格式,而static_cast会改变原来的格式;
class A {};
class B {};
A * a = new A;
B * b = reinterpret_cast<B*>(a);
//reinterpret_cast 对所有指针的处理与传统的类型转换符所作的一模一样。
《二》static_cast 静态转换.在编译期间处理
static_cast 允许执行任意的隐式转换和相反转换动作。(即使它是不允许隐式的)
- 用于基类和子类之间的指针或引用的转换。这种转换把子类的指针或引用转换为基类表示是安全的;
- 进行下行转换,把基类的指针或引用转换为子类表示时,由于没有进行动态类型检测,所以是不安全的;<被转换的父类没有被检查是否与目的类型相一致>
- 把void类型的指针转换成目标类型的指针(不安全).
- 用于内置的基本的数据类型之间的转换.
- 把任何类型的表达式转换成void类型的.
注意:static_cast不会转换掉被转换的内容的const,volatile,__unaligned属性
class Base {};
class Derived : public Base {};
Base *a = new Base;
Derived *b = static_cast<Derived *>(a);
static_cast除了能够对类指针进行操作,还可以被用来进行类中明确定义的转换,以及对基本类型的标准转换:
double d = 1.1234568;
int i = static_cast<int>(d);
《三》dynamic_cast 动态类型转换;也是向下安全转型;是在运行的时候执行;
通常用于基类和派生类之间的转换.转换时会进行类型安全检查。
- 不能用于内置的基本数据类型之间的转换.
- dynamic_cast转换成功的话返回的是类的指针或引用,失败返回null;
- dynamic_cast进行的转换的时候基类中一定要有虚函数,因为只有类中有了虚函数,才说明它希望让基类指针或引用指向其派生类对象的情况,这样才有意义.这是由于运行时类型检查需要运行时类型的信息,而这些信息存储在虚函数表中.
- 在类的转换时,在类层次间进行转换的时候,dynamic_cast和static_cast进行上行转换的时候效果是一样的;但是在进行下行转换的时候,dynamic_cast会进行类型检查所以它更安全.它可以让指向基类的指针转换为指向其子类的指针或是其兄弟类的指针;
class Base { virtual dummy(){}; };
class Derived : public Base { };
Base* b1 = new Derived;
Base* b2 = new Base;
Derived* d1 = dynamic_cast(b1); // succeeds
Derived* d2 = dynamic_cast(b2); // fails: returns NULL
如果类型转换被用在引用(reference)类型上,失败将会抛出bad_cast 类型的例外(exception):
class Base { virtual dummy(){}; };
class Derived : public Base { };
Base* b1 = new Derived;
Base* b2 = new Base;
Derived d1 = dynamic_cast(b1); // succeeds
Derived d2 = dynamic_cast(b2); // fails: exception thrown
《四》const_cast 去常转换;编译时执行
它主要作用同一个类型之间的去常和添加常属性之间的转换.不能用做不同的类型之间的转换.
它可以把一个不是常属性的转换成常属性的,同时它也可以对一个本是常属性的类型进行去常.
class C {};
const C *a = new C;
C *b = const_cast<C *>(a);
其它三种操作符是不能修改一个对象的常量性的。
注意:'const_cast'也能改变一个类型的volatile qualifier。
typeid
ANSI-C++ 还定义了一个新的操作符叫做 typeid ,它检查一个表达式的类型:
typeid (expression)
这个操作符返回一个类型为type_info的常量对象指针,这种类型定义在标准头函数中。这种返回值可以用操作符 == 和 != 来互相进行比较,也可以用来通过name()函数获得一个描述数据类型或类名称的字符串,例如:
#include <iostream.h>
#include <typeinfo>
class CDummy { };
int main () {
CDummy* a,b;
if (typeid(a) != typeid(b)) {
cout << "a and b are of different types:\n";
cout << "a is: " << typeid(a).name() << '\n';
cout << "b is: " << typeid(b).name() << '\n';
}
return 0;
}