C++有更严格的限制允许的类型转换,并添加4个类型转换操作符,使转换过程更规范:
- dynamic_cast;
- const_cast;
- static_cast;
- reinterpret_cast。
可以根据目的选择一个适合的操作符,而不是使用通用的类型转换。这指出了进行类型转换的原因,并让编译器能够检查程序的行为是否为设计者想法吻合。
dynamic_cast:该操作符的用途是,使得能够在类层次结构中进行向上转换,而不允许其他转换。例如:High和Low是两个类,而ph和pl的类型分别是High *和Low *,则仅当Low是High的可访问基类(直接或间接)时,语句:
pl = dynamic_cast<Low *> ph;
才将一个Low*指针赋给ph;否则该语句将空指针赋给pl。通常,该操作符的句法如下:
dynamic_cast <type_name> (expression)
该操作符的用途是,使得能够在类层次结构中进行向上转换,而不允许其他转换。
const_cast:操作符用于执行只有一种用途的类型转换,即改变值为const 或 volatile,其句法与dynamic_cast 操作符相同:
const_cast <type_name> (expression)
如果类型的其他方面也被修改,则上述类型转换将出错。也就是说,除了 const 和 volatile 特征(有或无)可以不同外,type_name 和 expression 的类型必须相同。再次假设High 和 Low 是两个类:
High bar;
const High * pbar = &bar;
...
High * pb = const_cast<High *>(pbar);//可以转换
const Low * pl = const_cast<const Low *>(pbar);//不可以转换
第一个类型转换使得 *p 成为一个可以用于修改 bar 对象值的指针,它删除const标签。第二个类型转换是非法的,因为它同时尝试将类型从const High * 改为 const Low *。
提供该操作符的原因是,有时候可能需要这样一个值,它在大多数时候是常量,而有时又是可以修改的。在这种情况下,可以将这个值声明为 const ,并在需要修改它的时候,使用 const_cast 。这也可以通过通用类型转换来实现,但通用转换也可能同时改变类型。
static_cast:操作符的句法与其他类型转换操作符相同:
static_cast <type_name> (expression)
仅当type_name可被隐式转换为expression 所属的类型或 expression 可被隐式转换为type_name 所属的类型时,上述转换才是合法的,否则将出错。假设 High 是 Low 的基类,而Pond 是一个无关的类,则从High 到 Low 的转换、从Low 到 High 的转换都是合法的,而从Low 到 Pond 的转换是不允许的:
High bar;
Low blow;
...
High * pb = static_cast<High *>(&blow);//可行,向上转换
Low * pl = static_cast<Low *>(&bar);//可行,向下转换
Pond * pmer = static_cast<Pond *>(&blow);//不行
第一种转换是合法的,因为向上转换可以显示地进行。第二种转换是从基类指针到派生类指针,在不进行显示转换的情况下,将无法进行。但由于无须进行类型转换,便可以进行另一个方向的类型转换,因此使用static_cast 来进行向下转换是合法的。
reinterpret_cast:操作符用于天生危险的类型转换,它不允许删除const ,但会指向其它令人生厌的操作。
使用reinterpret_cast 可以简化对这种行为的跟踪操作。