在C++中我们可以将一些类的共性编写到一个抽象的类中叫他抽象类(ABC abstract base class)
这个类中必须包含一个纯虚函数,抽象类不能定义出对象,但是可以作为其他类的基类。在抽象
类中可以对纯虚函数进行定义也可以不定义,但是注意纯虚函数一般是通过抽象类派生出来的派
生类的差异性函数原型,及不能在抽象类中实现的函数。那么抽象类的特点为:
1、至少包含一个纯虚函数
2、纯虚函数可以定义也可以不定义,但是一般是派生类之间的差异函数不能实现的函数
3、抽象类不能用于定义对象,但是可以声明抽象类的指针和引用
4、抽象类包含析构函数、构造函数。
5、纯虚函数包含虚函数的所有特点,比如向上转换时候基类指针自适应、通过vtbl
(virtual function table)
实现等。
那么下面说明一下纯虚函数,纯虚函数可以包含定义也可以不包含定义,当然前面说过既然成为
纯虚函数一般是不能在抽象类中实现的函数
实际上在虚函数原型中
后面加上 = 0 即可如:
vritual test(int a) = 0 ;
可以将抽象ABC类看做一种必须的接口,派生类覆盖其纯虚函数,这样迫使派生类遵守
ABC类的接口规则,让设计人员能够制定接口约定,这样确保从抽象ABC类继承的所有的
派生类支持抽象类的约定的功能接口.
我们还是以C++ Primer Plus列子的头文件作为说明
点击(此处)折叠或打开
- #include<iostream>
#ifndef ACCTABC_H_
#define ACCTABC_H_
#include<string>
using namespace std;class AcctABC
{
private:
string fullName;
long acctNum;
double balance;
protected:
struct Formatting
{
ios_base::fmtflags flag;
streamsize pr;
};
const string& FullName() const{
return fullName;
}
long AcctNum() const {
return acctNum;
}
Formatting SetFormat() const;
void Restore(Formatting& f) const;
public:
AcctABC(const string& s="Nullbody",long an= -1,double bal= 0.0);
void Deposit(double amt);
double Balance() const{return balance;};
virtual void Withdraw(double amt) = 0; //pure virtual function
virtual void ViewAcct() const = 0;//pure virtual function
virtual ~AcctABC(){}
};class Brass:public AcctABC
{
public:
Brass(const string& s="Nullbody",long an=-1,double bal = 0.0):AcctABC(s,an,bal){}
virtual void Withdraw(double amt); //redefine pure virtual function
virtual void ViewAcct() const; //redefine pure virtual function
virtual ~Brass(){};
};class BrassPlus:public AcctABC
{
private:
double maxLoan;
double rate;
double owesBank;
public:
BrassPlus(const string& s="Nullbody",long an = -1,double bal=0.0,double ml = 500,double r=0.10);
BrassPlus(const Brass& ba,double ml=500,double r=0.1);
virtual void ViewAcct() const;//redefine pure virtual function
virtual void Withdraw(double amt);//redefine pure virtual function
void ResetMax(double m){maxLoan=m;}
void ResetOwes(){owesBank=0;}
virtual ~BrassPlus(){}
};
#endif
显然Brass和BrassPlus中包含了很多相同点,我们将他们
抽象出来,但是他们的不同点是
virtual void Withdraw(double amt);
virtual void ViewAcct() const;
实现的不同,并且brassPlus中多了一些数据成员
所以我们抽象出了AcctABC包含了共同点,
对实现不同的函数Withdraw和ViewAcct定义为
纯虚函数
virtual void Withdraw(double amt) = 0; //pure virtual function
virtual void ViewAcct() const = 0;//pure virtual function
让他随后的继承类中自己实现