多态数组
- 不要以多态的形势,处理数组
纯虚函数
virtual f() const=0;
对象切片
- 虚函数或者向上类型转换,对于对象,使用值传递,而不是引用或者指针,会被切片为合适于目的子对象
- 换句话,虚函数无效,变为向上类型转换
运行时多态
- C++支持多态:虚函数+RTTI+向上类型转换
- 向上类型转换
- 虚函数
- RTTI=向下类型转换
虚函数的不足
//家用电器管理系统的设计
//抽象基类定义公共操作
class HomeED
{
public:
virtual void open()=0;
virtual void close()=0;
virtual void Adjust (bool updown)=0;
};
class EF: public HomeED // 电扇
{
public:
virtual void open()=0;
virtual void close()=0;
virtual void Adjust (bool updown)=0;
};
class ET:public HomeED // 电视
{
public:
virtual void open()=0;
virtual void close()=0;
virtual void Adjust (bool updown)=0;
//
virtual void playvcd(); // 播放vcd
};
enum Command{open,close,adust,palyvcd};
class DeviceController //控制类
{
public:
Command GetCommand() {...} //获取命令
void ContolThem(HomeED); //控制方法
};
void DeviceController:: ContolThem(HomeED &devie)
{
Command cmd=GetCommand();
switch(cmd)
{
case OPEN:
deive.open();
break;
case CLOSE:
deive.close();
break;
.....
case playvcd: //遇到问题,无法实现
}
}
- playvcd并非公共接口
RTTI
动态运行识别
* 异常处理机制+虚函数的补充
type_of
- 需要为RTTI提供一个type_of的类型
- RTTI的内存开销+type_of的内存开销
- RTTI运行时检索对象,需要时间开销
- 获取运行时type_of,操作符:typeid和daynamic_cast
- type_of由三个成员函数: operator==(),operator!=()和name()
typeid
- typeid,以对象或者类型为参数,返回一个匹配的const type_info对象—–表明该对象的确切类型
void DeviceController:: ContolThem(HomeED &devie)
{
Command cmd=GetCommand();
switch(cmd)
{
case OPEN:
.....
case PLAYVCD: //遇到问题,无法实现
if(typeid(device)==typeid(Television))
//typeid重载了运算符==,所以可以比较左右,为真,则播放vcd
{
Televison *pTemp=static_cas<Television*>(&device);
pTemp->PlayVCD();
} else
{
MsgBox("This device cannot play VCD!");
}
}
}
static_cast :
- device只可以是HomeED的派生类,因为抽象类不可以实例化
- static_cast告诉编译器device是什么类型
dynamic_cats<>
- typeid可以返回一个对象的确切类型,而不是基类型
- 识别继承后的动态识别
- upcast
- downcast