抽象类作为可从中派生更具体的类的一般概念的表达。 无法创建抽象类类型的对象。 但可以使用指向抽象类类型的指针和引用。
可以通过声明至少一个纯虚拟成员函数来创建抽象类。 这是使用 pure 说明符 () 语法声明的虚函数= 0
。 派生自抽象类的类必须实现纯虚函数或者它们必须也是抽象类。
请考虑虚函数中所述的示例。 类 Account
的用途是提供通用功能,但 Account
类型的对象太通用,因此没什么用。 这表示 Account
是抽象类的很合适的候选项:
// deriv_AbstractClasses.cpp
// compile with: /LD
class Account {
public:
Account( double d ); // Constructor.
virtual double GetBalance(); // Obtain balance.
virtual void PrintBalance() = 0; // Pure virtual function.
private:
double _balance;
};
此声明与上一个声明的唯一区别是,PrintBalance
是用 pure 说明符 (= 0
) 声明的。
抽象类限制
抽象类不能用于:
变量或成员数据
自变量类型
函数返回类型
显式转换的类型
如果抽象类的构造函数调用一个纯虚函数,无论是以直接还是间接方式,结果都是不确定的。 但是,抽象类的构造函数和析构函数都可以调用其他成员函数。
定义的纯虚函数
抽象类中的纯虚函数可以定义或具有实现。 只能使用完全限定的语法调用此类函数:
abstract-class-name::function-name()
在设计基类包含纯虚析构函数的类层次结构时,定义的纯虚函数非常有用。 这是因为对象销毁期间会始终调用基类析构函数。 请考虑以下示例:
// deriv_RestrictionsOnUsingAbstractClasses.cpp
// Declare an abstract base class with a pure virtual destructor.
// It's the simplest possible abstract class.
class base
{
public:
base() {}
// To define the virtual destructor outside the class:
virtual ~base() = 0;
// Microsoft-specific extension to define it inline:
// virtual ~base() = 0 {};
};
base::~base() {} // required if not using Microsoft extension
class derived : public base
{
public:
derived() {}
~derived() {}
};
int main()
{
derived aDerived; // destructor called when it goes out of scope
}
该示例演示了 Microsoft 编译器扩展如何支持向纯虚 ~base()
添加内联定义。 还可以使用 base::~base() {}
.在类外定义它。
当对象 aDerived
超出范围时,将调用类 derived
的析构函数。 编译器生成代码以在 derived
析构函数之后隐式调用类 base
的析构函数。 纯虚函数 ~base
的空实现确保至少函数的某个实现存在。 如果没有,链接器将为隐式调用生成未解析的外部符号错误。
注意
在前面的示例中,纯虚函数 base::~base
是从 derived::~derived
隐式调用的。 还可使用完全限定的成员函数名称显式调用纯虚函数。 此类函数必须具有实现,否则调用会在链接时导致错误。