uacs2024

导航

C++ 接口(抽象类) 虚函数

接口描述了类的行为和功能,而不需要完成类的特定实现。

C++ 接口是使用抽象类来实现的,抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念。

如果类中至少有一个函数被声明为纯虚函数,则这个类就是抽象类。纯虚函数是通过在声明中使用 "= 0" 来指定的

class Box
{
   public:
      // 纯虚函数
      virtual double getVolume() = 0;
   private:
      double length;      // 长度
      double breadth;     // 宽度
      double height;      // 高度
};

设计抽象类(通常称为 ABC)的目的,是为了给其他类提供一个可以继承的适当的基类抽象类不能被用于实例化对象,它只能作为接口使用。如果试图实例化一个抽象类的对象,会导致编译错误。

因此,如果一个 ABC 的子类需要被实例化,则必须实现每个纯虚函数,这也意味着 C++ 支持使用 ABC 声明接口。如果没有在派生类中重写纯虚函数,就尝试实例化该类的对象,会导致编译错误。

可用于实例化对象的类被称为具体类

抽象类的实例

下面的实例,基类 Shape 提供了一个接口 getArea(),在两个派生类 Rectangle 和 Triangle 中分别实现了 getArea()

 1 #include <iostream>
 2 using namespace std;
 3 // 基类
 4 class Shape 
 5 {
 6 public:
 7    // 提供接口框架的纯虚函数
 8    virtual int getArea() = 0;
 9    void setWidth(int w)
10    {
11       width = w;
12    }
13    void setHeight(int h)
14    {
15       height = h;
16    }
17 protected:
18    int width;
19    int height;
20 };
21 // 派生类
22 class Rectangle: public Shape
23 {
24 public:
25    int getArea()
26    { 
27       return (width * height); 
28    }
29 };
30 class Triangle: public Shape
31 {
32 public:
33    int getArea()
34    { 
35       return (width * height)/2; 
36    }
37 };
38 int main(void)
39 {
40    Rectangle Rect;
41    Triangle  Tri;
42  
43    Rect.setWidth(5);
44    Rect.setHeight(7);
45    // 输出对象的面积
46    cout << "Total Rectangle area: " << Rect.getArea() << endl;
47  
48    Tri.setWidth(5);
49    Tri.setHeight(7);
50    // 输出对象的面积
51    cout << "Total Triangle area: " << Tri.getArea() << endl; 
52  
53    return 0;
54 }

设计策略

面向对象的系统可能会使用一个抽象基类为所有的外部应用程序提供一个适当的、通用的、标准化的接口。然后,派生类通过继承抽象基类,就把所有类似的操作都继承下来。

外部应用程序提供的功能(即公有函数)在抽象基类中是以纯虚函数的形式存在的。这些纯虚函数在相应的派生类中被实现。

这个架构也使得新的应用程序可以很容易地被添加到系统中,即使是在系统被定义之后依然可以如此。

 

定义一个函数为虚函数,不代表函数为不被实现的函数。

定义他为虚函数是为了允许用基类的指针来调用子类的这个函数。

定义一个函数为纯虚函数,才代表函数没有被实现。

定义纯虚函数是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数。

 

1)虚函数可以在类中声明,也可以在类的外部声明,编译器会自动将它们转换为虚函数;但是纯虚函数只能在类中声明,而不能在类的外部声明。

2)虚函数可以有实现,也可以没有实现;而纯虚函数没有实现,不可以有实现。

3)虚函数可以在子类中覆盖,也可以不被覆盖;而纯虚函数必须在子类中覆盖,否则编译器将报错。

4)虚函数可以被多态调用,也可以被静态调用;而纯虚函数只可以被多态调用,不可以被静态调用。

posted on 2024-03-03 20:38  ᶜʸᵃⁿ  阅读(11)  评论(0编辑  收藏  举报