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...
但无法在不重新声明每个子类中的接口的情况下弄清楚如何。
答案 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;