有人可以解释,如果我们有一个带有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
.cpp文件
#include "../include/Algorithm.h"
Algorithm::Algorithm(vector<Event>& dataset):dataset(&dataset){}
Algorithm::~Algorithm(){}
鉴于声明纯虚函数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
.cpp文件
#include "../include/SelectAlgorithmRandom.h"
SelectAlgorithmRandom::SelectAlgorithmRandom(vector<Event>& dataset):Algorithm(dataset){}
SelectAlgorithmRandom::~SelectAlgorithmRandom(){}
void SelectAlgorithmRandom::run(){
// TODO
}
答案 0 :(得分:6)
您必须添加声明,因为C ++标准要求在类定义本身中声明类的每个成员:
类定义中的成员规范声明了该类的完整成员集;没有成员可以添加到其他地方。
成员指的是功能和数据。 Algorithm
中存在纯虚函数的事实并不自动意味着SelectAlgorithmRandom
也将定义它。可以通过继承层次结构的多个层来保持类的抽象。
要定义run
函数,必须在类定义中明确指定该intent。
顺便说一句,在现代C ++中,最好将该函数声明为意味着作为覆盖:
void run() override;
这样编译器会根据基类版本的定义对其进行检查,以确保您真正覆盖基类中的某些内容,而不是添加重载或某些不相关的函数。
答案 1 :(得分:1)
简而言之,如果你想实现polymorphism
使用虚方法和指向基类的指针。
class A{
public:
virtual void F(){std::cout << "Base A::Foo()" << std::endl;}
};
class B : public A{
public:
void F(){std::cout << "B::Foo()" << std::endl;}
};
现在主要:
int main(){
A* ptrA = new B;
ptrA->Foo();
return 0;
}
正如您在上面所看到的,根据Foo
指向的对象类型调用方法ptrA
。
答案 2 :(得分:1)
您必须在std::memset (&st_arr[0], 0, sizeof(st_arr));
声明中声明run()
函数,以表明您确实打算为该类定义它。
如果没有,SelectAlgorithmRandom
也将是一个抽象类,并且该函数可以在另一个派生类中定义。也许有几个级别了。