C++规则的设计目标之一:保证“类型错误”绝不可能发生。
C++转换语法(旧式转换):
- (T)expression //将expression转为T
- T(expression) //将expression转为T
C++新式类型转换:
- const_cast:用来将对象的常量性转除
- dynamic_cast:安全向下转换,用来决定某对象是否归属继承体系中的某个类型。唯一无法由旧式语法执行的动作,也是唯一可能消耗重大运行成本的转换动作。
- reintepret_cast:意图执行低级转型。实际动作可能取决于编译器,这也表示不可以移植。例如:将一个pointer to int转换为int型。
- static_cast:强制隐式类型转换。例如:将non-const对象转换为const对象,或将int转为double等。
注:任何一种转换真的令编译器编译出运行期间执行的代码。
很多应用框架要求子类内的virtual函数代码的第一件事就先调用基类的对应函数。
例如:
class SpecialWindow : public Window
{
public:
virtual void onResize() {
Window::onResize();
...
}
};
dynamic_cast许多实现版本执行很慢。通常是因为想在一个认定为子类对象身上执行子类操作函数,但仅有一个指向基类的指针或引用,只能靠他们处理对象。
避免使用dynamic_cast的做法:
- 使用容器并在其中存储直接指向子类对象的指针(智能指针)。
class Window {...};
class SpecialWindow : public Window {
public:
void blink();
...
};
typedef std::vector<std::shared_ptr<Window>> VPW;
VPW winPtrs;
...
for (VPW::iterator iter = winPtrs.begin();
iter != winPtrs.end(); ++iter) {
(*iter)->blink(); //直接实现,无需dynamic_cast
}
注:这种做法无法在同一个容器内存储指针“指向所有可能之各种Window派生类”。
通过基类接口处理“所有可能之各种Window派生类”,在基类内提供虚函数做想对各个Window派生类做的事。
class Window {
public:
virtual void blink() { } //缺省实现代码,什么都没做
...
};
class SpecialWindow : public Window {
public:
virtual void blink() { ... };
};
typedef std::vector<std::shared_ptr<Window>> VPW;
VPW winPtrs;
for (VPW::iterator iter = winPtrs.begin();
iter != winPtrs.end();
++iter) {
(*iter)->blink();
}
需要绝对避免连串的dynamic_cast