如何在实现文件中实现虚方法?

时间:2016-01-01 15:07:41

标签: c++

C ++ noob问题:

假设我想使用一个带有多个方法的抽象类作为接口:

// this is AbstractBase.hpp

class AbstractBase
{
public:
  virtual int foo() = 0;
  virtual int bar() = 0;
  // imagine several more pure virtual methods are here
};

我想要一个实现所有虚拟方法的子类,我不想在头文件中实现它们,而是在它们的实现文件中实现它们。

我真的必须在这样的子类声明中再次声明所有这些方法吗?我认为应该有办法避免这一步(来自ObjC,Java)

// this is Concrete.hpp

class Concrete : public AbstractBase
{
public:
  int foo();
  int bar();
  // need to copy paste all the method declarations here again...? why?
};

我想要做的是在实现文件中实现这样的方法:

// this is Concrete.cpp

#include "Concrete.hpp"

int Concrete::foo()
{
    return 666;
}

// etc...

但无法在不重新声明每个子类中的接口的情况下弄清楚如何。

5 个答案:

答案 0 :(得分:11)

如果将定义与声明“Java风格”结合起来,即可以避免第二次编写函数头签名,即

class Concrete : public AbstractBase
{
public:
  int foo() override {return 666;}
};

当您想要单独提供定义时,C ++不会让您避免声明步骤。

原因是声明是主要的,而定义是次要的。为了能够写

int Concrete::foo()
{
    return 666;
}
在您的CPP文件中,您需要告诉编译器Concrete有意在其标题中覆盖foo

答案 1 :(得分:5)

如果你喜欢一个abstrct基类,你必须让你的方法pur虚拟(只有声明没有实现(在你的方法声明后面写=0):

class AbstractBase
{
public:
  virtual int foo() = 0; // <- = 0 
  virtual int bar() = 0; // <- = 0
};

使用override关键字,因此如果基类中的mehtod解密更改,您将收到编译错误:

Concrete.hpp

class Concrete : public AbstractBase
{
public:
  int foo() override; // <- override
  int bar() override; // <- override
};

最终实现您的方法,就像您在问题中所做的那样:

Concrete.cpp

#include "Concrete.hpp"

int Conrete::foo()
{
    return 666;
}

int Conrete::bar()
{
    return 777;
}

但是你必须从子类中的基类声明所有那些抽象的方法。

答案 2 :(得分:4)

首先,正如LogicStuff在评论中所说,你 正确地做了。

其次:

  

//需要再次复制粘贴所有方法声明...?为什么呢?

因为你的子类

  • 不必实现所有(甚至任何)虚拟基类函数。它可能只覆盖其中一些,并将其他人留给更加派生的类

  • 允许添加其他方法和重载。

    如果你有一个包含许多方法的类,那么如果你还需要回顾它的所有基类(以及它们的所有基类)来找到它可能支持但未提及的其他方法,那就很奇怪了。

答案 3 :(得分:1)

您必须在子类中声明所有这些方法以及您想要实现的方法。

答案 4 :(得分:1)

您必须在子类中声明要覆盖的所有方法。

经常完成后,您可以使用宏来简化此操作。在基类的头文件中定义宏,如下所示:

#define ABSTRACTBASE_OVERRIDE_ALL \
    int foo() override; \
    int bar() override;