纯虚函数
纯虚函数是指没有函数体,定义时在函数名后加上=0,如下代码所示
class Shape
{
public:
virtual double calcArea()//虚函数
{return 0;}
virtual double calcPerimeter()=0;//纯虚函数
protected:
int m_iEge;
};
在虚函数指针指向的虚函数表中,calcPerimeter=0。含有纯虚函数的类叫做抽象类,抽象类无法实例化对象(无论堆中或栈中),当抽象类的子类,将基类中的纯虚函数都进行赋值以后,即不是=0后才能够实例化。
接口类
仅含有纯虚函数的类叫做接口类,接口类没有数据成员,仅有纯虚成员函数。如下代码所示
class Shape
{
public:
virtual double calcArea()=0;
virtual double calcPerimeter()=0;
};
运行时类型识别(RTTI Run-Time Type Identification)。
在下面的代码中,能不能做到判断对象类型完成注释的部分,就要用到RTTI
class Flyable
{
public:
virtual void takeoff() = 0;
virtual void land()=0;
};
class Bird : public Flyable
{
public:
void foraging(){......}
virtual void takeoff(){......}
virtual void land(){......}
private:
...
};
class Plane : public Flyable
{
public:
void carry(){......}
virtual void takeoff(){......}
virtual void land(){......}
};
void doSomething(Flyable *obj)
{
obj->takeoff();
//如果是bird,则觅食
//如果是plane,则运输
obj->land();
}
所使用的的代码如下所示
void doSomething(Flyable *obj)
{
obj->takeoff();
cout << typeid(*obj).name()<< endl;//输出当前指针指向的类型名
if (typeid(*obj) == typeid(Bird))//对类型进行比对
{
Bird *bird = dynamic_cast<Bird *>(obj);//进行类型的转化
bird->foraging();
}
obj->land();
}
同样我们在使用dynamic_cast的时候有以下几点注意事项
1.只能用于指针和引用的转换
2.要转换的类型中必须含有虚函数
3.转换成功,返回的是子类的地址,失败则是NULL
同样在使用Typeid时也有以下几点注意事项
1.type_id返回的是一个Type_info对象的引用
2.如果想通过基类的指针获得派生类的数据类型,基类必须带有虚函数
3.只能获取对象的实际类型
#include <typeinfo>//需要该头文件
int main()
{
Flyable *p = new Bird();
cout << typeid(p).name() << endl; //打印出Flyable *
cout << typeid(*p).name() << endl;//打印出Bird
return 0;
}
异常处理
异常是指程序在运行过程中出现的错误,这些错误并不是我们所希望的,但是往往在某种情况下这种错误会出现。
异常处理就是对可能发生异常的地方做出预见性的安排,如果我们做出的安排合理,并且能够给出人性化的提示,那么使用者就不会觉得突兀
进行异常处理用到两个关键字
1. try….catch…. 尝试(运行正常的逻辑)……捕获……. [Try catch是一对多的关系]
2. throw 抛出异常
基本思想:主逻辑与异常处理分离
常见的异常:
1.数组下标越界
2.除数为0
3.内存不足