参考C++ prime 第四版 9.1.1节
- dynamic_cast 是个在运行时执行的操作符
- dynamic_cast的作用: dynamic_cast用来把一个类的指针(引用)转换成同一类层次结构的其它类的指针(引用)
- dynamic_cast每次执行两个操作:类型检查和类型转换,只有在类型检查正确的情况下,才进行类型转换。
- 对于类类型指针之间的转换,可以通过dynamic_cast操作符的返回值进行判断,如果转换失败会返回0,通过if判断可以查看是否转换成功。
- 对于类引用类型之间的转换,如果转换失败会抛出异常,对抛出的异常进行处理时会给程序带来相应的开销,如构造异常对象等。
dynamic_cast 被用来执行从基类指针到派生类指针的安全转换,它常常被称为安全的向下转换 downcasting。 当我们必须使用派生类的特性,而该特性又没有出现在基类中时我们常常使用 dynamic_cast, 用指向基类类型的指针来操纵派生类类型的对象,通常通过虚拟函数自动处理 。但是在某些情形下,使用虚拟函数是不可能的 。dynamic_cast 为这些情形提供了替代的机制,但是这种机制比虚拟成员函数更易出错,应该小心使用。 如果我们希望扩展某个类库,不能增加虚拟成员函数,但我们可能仍然希望增加功能,在这种情况下,就必需使用 dynamic_cast 。
下面是一个dynamic_cast使用例子
场景:我们购买了一个类库产品,该类实现计算薪水功能:假如公司有两类员工,项目经理和程序员,对于代码实现方式,我们可以定义一个基类employee,里面定义虚函数getSalary进行薪水的计算。项目经理类manager和程序员programmer继承employee实现相应的getSalary虚函数。但是由于薪资改革,需要给程序员programmer分发奖金,这样薪水的计算方式需要发生变化,直接的方法是修改基类
添加奖金的计算虚拟函数getBonus,然后所有的基类实现该函数,重新编译程序,但是该类是购买产品该方法是行不通的(实际未必如此,只是举个例子),我们可以单独为programmer类实现getBonus方法,此时需要dynamic_cast操作符,把基类指针转换成programmer指针,然后调用programmer的getBonus方法。
代码如下
#include <iostream>
using namespace std;
class employee {
public:
virtual int getSalary() = 0;
};
class manager:public employee{
public:
virtual int getSalary() {
return 700;
}
};
class programmer:public employee{
public:
virtual int getSalary() {
return 200;
}
int getBonus() {
return 300;
}
};
int get_salary(employee *pe) {
int salary = 0;
programmer *prg = dynamic_cast<programmer*>(pe);
if (prg != NULL) {
salary = prg->getSalary() + prg->getBonus();
cout<<"programmer ";
}
else {
salary = pe->getSalary();
cout<<"manager ";
}
return salary;
}
int _tmain(int argc, _TCHAR* argv[])
{
employee *prg = new programmer();
employee *pmg = new manager();
cout<<"programmer : "<<get_salary(prg)<<endl;
cout<<"mamager: "<<get_salary(pmg)<<endl;
return 0;
}