<base />必须是先前定义的类或结构

时间:2018-08-23 11:42:08

标签: c++

我有一个基类的标头和cpp文件,以及一个派生类的标头和cpp文件。我在派生类的头文件中收到以下错误:

  

Base必须是先前定义的类或结构。

我已将基类头文件包含在派生类头文件中。我意识到基类的定义不在头文件中,但我读到包括cpp文件不是一个好习惯。另外,如果我将两个类定义都放在同一个头文件中,并且在同一个cpp文件中实现了这两个类,则没有错误。

由于代码是针对学校项目的,因此我将给出示例,而不是确切的代码:

base.h

#ifndef _base_h_
#define _base_h_

#include "derived.h"

class Base {
public:

  void start();
  void waitToComplete();
  virtual ~Base();

  static void sleep(Time timeToSleep);

protected:

  friend class Derived;
  Base ();
  virtual void run() {}
};

#endif

派生.h

#ifndef _derived_h_
#define _derived_h_

#include "base.h"

class Derived : public Base{
public:
  Derived();
  void run();
  void start();
  ~Derived() ;
};
#endif

1 个答案:

答案 0 :(得分:2)

这是典型的循环依赖项Base类不需要Derived的完整定义,只知道它存在。这是通过转发声明完成的。

有了正确的前向声明,base.h头文件不需要包含derived.h头文件:

//File: base.h
#ifndef _base_h_
#define _base_h_

// Do not include header file for Derived
// Only do forward declaration
class Derived;    

class Base {
public:

void start();
void waitToComplete();
virtual ~Base();

static void sleep(Time timeToSleep);

protected:

friend class Derived;
Base ();
virtual void run() {}
};

#endif

一些不相关的注释:

  • Base::run函数应该是 pure 虚拟函数:

    virtual void run() = 0;
    
  • Derived类是否应该真正覆盖start函数?

  • 如果要覆盖派生类中的函数,则应使用override特殊修饰符标识符:

    void run() override;