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...
但无法弄清楚如何在不重新声明每个子类中的接口的情况下.
如果将定义与声明"Java样式"结合起来,即可以避免第二次编写函数头签名,即
class Concrete : public AbstractBase { public: int foo() override {return 666;} };
当您想单独提供定义时,C++不允许您避免声明步骤.
这样做的原因是声明是主要的,而定义是次要的.为了能够写
int Concrete::foo() { return 666; }
在您的CPP文件中,您需要告诉编译器Concrete
有意foo
在其标头中覆盖.
如果您喜欢抽象的基类,则必须使方法成为纯虚拟的(仅声明而不实现)(写=0
在方法的声明后面):
class AbstractBase { public: virtual int foo() = 0; // <- = 0 virtual int bar() = 0; // <- = 0 };
使用override
关键字,因此,如果基类中的方法的声明发生变化,则会出现编译错误:
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; }
但是您必须从抽象的子类的基类中声明所有这些方法。