为什么我需要在子类中重新声明`virtual`方法?[C++/Polymorphism]

e.d*_*vic 0 c++ polymorphism

有人可以解释一下,如果我们有一个带有virtual成员函数的抽象类,为什么我们需要在子类中再次声明它?例如,请参见下面的示例

抽象类

.h文件

#ifndef ALGORITHM_H
#define ALGORITHM_H

#include <vector>
#include "Event.h"

using std::vector;

class Algorithm{
protected:
  vector<Event>* dataset;
public:
  Algorithm(vector<Event>& dataset);
  virtual ~Algorithm();

  virtual void run() = 0;
};

#endif
Run Code Online (Sandbox Code Playgroud)

.cpp文件

#include "../include/Algorithm.h"

Algorithm::Algorithm(vector<Event>& dataset):dataset(&dataset){}
Algorithm::~Algorithm(){}
Run Code Online (Sandbox Code Playgroud)

鉴于run声明纯虚函数,通过扩展此类,我的期望是它只需要实现.但是,它仍然需要在类中声明扩展此抽象类.

子类

.h文件

#ifndef SELECT_ALGORITHM_RANDOM_H
#define SELECT_ALGORITHM_RANDOM_H

#include "Algorithm.h"

class SelectAlgorithmRandom : public Algorithm{
public:
  SelectAlgorithmRandom(vector<Event>& dataset);
  ~SelectAlgorithmRandom();

  void run(); // <-- why do I need this here, and doesn't it defy the purpose of me declaring virtual `run` function in `Algorithm`? 
};

#endif
Run Code Online (Sandbox Code Playgroud)

.cpp文件

#include "../include/SelectAlgorithmRandom.h"

SelectAlgorithmRandom::SelectAlgorithmRandom(vector<Event>& dataset):Algorithm(dataset){}
SelectAlgorithmRandom::~SelectAlgorithmRandom(){}

void SelectAlgorithmRandom::run(){
  //  TODO
}
Run Code Online (Sandbox Code Playgroud)

Sto*_*ica 6

您必须添加声明,因为C++标准要求在类定义本身中声明类的每个成员:

[class.mem]/1:

类定义中的成员规范声明了该类的完整成员集; 其他任何成员都无法添加.

成员指的是功能和数据.有一个纯虚函数的Algorithm事实并不自动意味着它SelectAlgorithmRandom也将定义它.可以通过继承层次结构的多个层来保持类的抽象.

要定义run函数,必须在类定义中明确指定该intent.

顺便说一下,在现代C++,最好声明函数是作为替代:

void run() override;
Run Code Online (Sandbox Code Playgroud)

这样编译器会根据基类版本的定义对其进行检查,以确保您真正覆盖基类中的某些内容,而不是添加重载或某些不相关的函数.