纯虚函数与抽象类
纯虚函数
一.纯虚函数
virtual … = 0;
•形如
class 类名
{
virtual 返回类型 函数名 (形参表) = 0;
};
的虚函数,称为纯虚函数或抽象方法
–class Shape
{
public: virtual void draw (void) const = 0;
};
•纯虚函数可以不定义,但如果定义,必须写在类的外部
–void Shape::draw (void) const { … }
•在基类的构造和析构函数中调用纯虚函数,结果将是未定义的。
通常会在链接阶段报告失败。如果该纯虚函数有定义,编译器将在给出警告之后,选择调用基类版本
抽象类
一.纯虚函数与抽象类
•至少包含一个纯虚函数的类称为抽象类
–class Abstract
{
void foo (void) { ... }
virtual void bar (void) { ... }
virtual void hum (void) = 0;
};
•纯虚函数因其所代表的抽象行为而无需或无法实现,包含此种函数的类亦因其所具有的一般性而表现出抽象的特征
•抽象类往往用来表示在对问题进行分析、设计的过程中所得出的抽象概念,是对一系列看上去不同,但本质上相同的具体概念的抽象
二.抽象类不能实例化为对象
•无论是直接定义,还是通过new运算符,抽象类永远不能实例化为对象
–Shape shape (…); // 错误
–Shape* shape = new Shape (…); // 错误
–void show (Shape shape); // 错误
–Shape make (void); // 错误
三.抽象类的子类
•抽象类的子类如果不对基类中的全部纯虚函数提供有效的覆盖,那么该子类就也是抽象类
–class A
{ // 抽象类
virtual void foo (void) = 0;
virtual void bar (void) = 0;
};
–class B : public A
{ // 抽象类
void foo (void) { ... }
void bar (int x, int y) { ... } // 没有覆盖A::bar,继承之
};
–class C : public B
{ // 具体类
void bar (void) { ... } // 覆盖B中从A继承的bar
};
纯抽象类
一.面向抽象
•全部由纯虚函数构成的抽象类称为纯抽象类或接口
•面向抽象编程,使得所有基于接口编写的代码,在子类被更替后,无需做任何修改或只需做很少的修改,就能在新子类上正确运行
–class Animal
{
virtual void eat (void) = 0;
virtual void run (void) = 0;
virtual void cry (void) = 0;
};
–Animal* animal = new Cat (...); // Dog, Ox, Sheep, ...
animal->eat ();
animal->run ();
animal->cry ();