51 C++ - 抽象基类和纯虚函数(pure virtual function)

简介: 51 C++ - 抽象基类和纯虚函数(pure virtual function)

在设计时,常常希望基类仅仅作为其派生类的一个接口。这就是说,仅想对基类进行向上类型转换,使用它的接口,而不希望用户实际的创建一个基类的对象。同时创建一个纯虚函数允许接口中放置成员原函数,而不一定要提供一段可能对这个函数毫无意义的代码。

做到这点,可以在基类中加入至少一个纯虚函数(pure virtual function),使得基类称为抽象类(abstract class).

  • 纯虚函数使用关键字virtual,并在其后面加上=0。如果试图去实例化一个抽象类,编译器则会阻止这种操作。
  • 当继承一个抽象类的时候,必须实现所有的纯虚函数,否则由抽象类派生的类也是一个抽象类。
  • Virtual void fun() = 0;告诉编译器在vtable中为函数保留一个位置,但在这个特定位置不放地址。

建立公共接口目的是为了将子类公共的操作抽象出来,可以通过一个公共接口来操纵一组类,且这个公共接口不需要事先(或者不需要完全实现)。可以创建一个公共类.

案例: 模板方法模式

//抽象制作饮品
class AbstractDrinking{
public:
  //烧水
  virtual void Boil() = 0;
  //冲泡
  virtual void Brew() = 0;
  //倒入杯中
  virtual void PourInCup() = 0;
  //加入辅料
  virtual void PutSomething() = 0;
  //规定流程
  void MakeDrink(){
    Boil();
    Brew();
    PourInCup();
    PutSomething();
  }
};
//制作咖啡
class Coffee : public AbstractDrinking{
public:
  //烧水
  virtual void Boil(){
    cout << "煮农夫山泉!" << endl;
  }
  //冲泡
  virtual void Brew(){
    cout << "冲泡咖啡!" << endl;
  }
  //倒入杯中
  virtual void PourInCup(){
    cout << "将咖啡倒入杯中!" << endl;
  }
  //加入辅料
  virtual void PutSomething(){
    cout << "加入牛奶!" << endl;
  }
};
//制作茶水
class Tea : public AbstractDrinking{
public:
  //烧水
  virtual void Boil(){
    cout << "煮自来水!" << endl;
  }
  //冲泡
  virtual void Brew(){
    cout << "冲泡茶叶!" << endl;
  }
  //倒入杯中
  virtual void PourInCup(){
    cout << "将茶水倒入杯中!" << endl;
  }
  //加入辅料
  virtual void PutSomething(){
    cout << "加入食盐!" << endl;
  }
};
//业务函数
void DoBussiness(AbstractDrinking* drink){
  drink->MakeDrink();
  delete drink;
}
void test(){
  DoBussiness(new Coffee);
  cout << "--------------" << endl;
  DoBussiness(new Tea);
}


目录
相关文章
|
3月前
|
存储 算法 程序员
C++ 11新特性之function
C++ 11新特性之function
52 9
|
4月前
|
编译器 C++
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
|
4月前
|
编译器 C++
virtual类的使用方法问题之静态和非静态函数成员在C++对象模型中存放如何解决
virtual类的使用方法问题之静态和非静态函数成员在C++对象模型中存放如何解决
|
4月前
|
编译器 C++
virtual类的使用方法问题之在C++中获取对象的vptr(虚拟表指针)如何解决
virtual类的使用方法问题之在C++中获取对象的vptr(虚拟表指针)如何解决
|
4月前
|
编译器 C++
C++的基类和派生类构造函数
基类的成员函数可以被继承,可以通过派生类的对象访问,但这仅仅指的是普通的成员函数,类的构造函数不能被继承。构造函数不能被继承是有道理的,因为即使继承了,它的名字和派生类的名字也不一样,不能成为派生类的构造函数,当然更不能成为普通的成员函数。 在设计派生类时,对继承过来的成员变量的初始化工作也要由派生类的构造函数完成,但是大部分基类都有 private 属性的成员变量,它们在派生类中无法访问,更不能使用派生类的构造函数来初始化。 这种矛盾在C++继承中是普遍存在的,解决这个问题的思路是:在派生类的构造函数中调用基类的构造函数。 下面的例子展示了如何在派生类的构造函数中调用基类的构造函数:
|
5月前
|
存储 C++ 运维
开发与运维函数问题之使用C++标准库中的std::function来简化回调函数的使用如何解决
开发与运维函数问题之使用C++标准库中的std::function来简化回调函数的使用如何解决
55 6
|
5月前
|
存储 C++
【C++】string类的使用③(非成员函数重载Non-member function overloads)
这篇文章探讨了C++中`std::string`的`replace`和`swap`函数以及非成员函数重载。`replace`提供了多种方式替换字符串中的部分内容,包括使用字符串、子串、字符、字符数组和填充字符。`swap`函数用于交换两个`string`对象的内容,成员函数版本效率更高。非成员函数重载包括`operator+`实现字符串连接,关系运算符(如`==`, `&lt;`等)用于比较字符串,以及`swap`非成员函数。此外,还介绍了`getline`函数,用于按指定分隔符从输入流中读取字符串。文章强调了非成员函数在特定情况下的作用,并给出了多个示例代码。
|
7月前
|
程序员 编译器 C++
C++中的函数重载(Function Overloading)
C++中的函数重载(Function Overloading)
81 2
|
6月前
|
算法 编译器 C++
C++多态与虚拟:函数重载(Function Overloading)
重载(Overloading)是C++中的一个特性,允许不同函数实体共享同一名称但通过参数差异来区分。例如,在类`CPoint`中,有两个成员函数`x()`,一个返回`float`,另一个是设置`float`值。通过函数重载,我们可以为不同数据类型(如`int`、`float`、`double`)定义同名函数`Add`,编译器会根据传入参数自动选择正确实现。不过,仅返回类型不同而参数相同的函数不能重载,这在编译时会导致错误。重载适用于成员和全局函数,而模板是另一种处理类型多样性的方式,将在后续讨论中介绍。
|
7月前
|
数据安全/隐私保护 C++
C++中的虚函数、纯虚函数与函数重写的技术性探讨
C++中的虚函数、纯虚函数与函数重写的技术性探讨
93 0

热门文章

最新文章