C++的纯虚函数实现和头文件

Posted

技术标签:

【中文标题】C++的纯虚函数实现和头文件【英文标题】:C++'s pure virtual function implementation and header files 【发布时间】:2011-01-13 00:29:41 【问题描述】:

当有问题的类分为*.h*.cpp 文件时,我在实现从某个抽象类继承的纯虚函数时遇到了一些麻烦。编译器(g++)告诉我,由于纯函数的存在,派生类无法实例化。

/** interface.h**/
namespace ns

    class Interface 
        public:
            virtual void method()=0;
    


/** interface.cpp**/
namespace ns

    //Interface::method()() //not implemented here


/** derived.h **/
namespace ns

    class Derived : public Interface 
        //note - see below
    


/** derived.cpp **/
namespace ns

    void Derived::Interface::method()  /*doSomething*/ 


/** main.cpp **/
using namespace ns;
int main()

    Interface* instance = new Derived; //compiler error

这是否意味着我必须在接口的*.hderived.h 中两次声明 method()?没有其他办法了吗?

【问题讨论】:

首先,没有理由拥有一个只有空白命名空间的 .cpp 文件。包含抽象类的标头不需要实现文件。 【参考方案1】:

你必须在子类中声明你的方法。

// interface.hpp
class Interface 
public:
    virtual void method()=0;


// derived.hpp
class Derived : public Interface 
public:
    void method();


// derived.cpp
void
Derived::method()

    // do something

【讨论】:

我想你的意思是 declare(不是定义)。 @MikeSlutsky 是的,我做到了。 @robert 谢谢你的回答。你能详细说明原因吗?来自Java,必须这样做似乎很脏。当我们在基接口中有许多不同的派生类和许多方法时,我们需要更改很多文件以防基接口发生变化。 @ManuelSelva 你不能在一个类中定义一个方法,除非它在那个类中声明。这与此类是否派生于任何东西无关。【参考方案2】:

你忘了声明Derived::method()

您至少尝试定义它,但写了Derived::Interface::method()而不是Derived::method(),但您甚至没有尝试声明它。因此它不存在。

因此,Derived 没有method(),因此来自Interface 的纯虚函数method() 没有被覆盖......因此,Derived 也是纯虚函数,不能被实例化。

另外,public void method()=0; 不是有效的 C++;它看起来更像 Java。纯虚成员函数实际上必须是虚函数,但你没有写virtual。访问说明符后跟一个冒号:

public:
    virtual void method() = 0;

【讨论】:

空位可能是错字,也不是java。 @time4tea:确实它也不是有效的 Java,但是由于缺少冒号以及访问说明符已被视为加入声明的含义,它比 C++ 更接近该死的景象! 语法是我的错字,请参阅我对开篇的评论:) 对此感到抱歉。此外,Derived::Interface::method() 是我尝试定义一个应该从接口继承的函数。我最初的问题是“我可以实现(定义)一个继承的纯虚函数而不在派生类的.h 文件中明确声明它吗?”。我想这样做的原因是避免当类从多个接口继承时使我的头文件混乱,每个接口都包含几个纯虚拟...... @Neo:答案是否定的。 :) @Thomalak Geret'kal:啊。遗憾。 :( 非常感谢您的帮助 :)【参考方案3】:

你也没有正确调用构造函数——它也是一个方法;

 Interface* instance = new Derived;

应该是

 Interface* instance = new Derived();

【讨论】:

这是 C++,您当然可以使用 new Derived;new Derived(); 创建对象。两者之间有一定的区别(参见this answer),但在这种情况下它们是等价的,因为没有要初始化的字段。

以上是关于C++的纯虚函数实现和头文件的主要内容,如果未能解决你的问题,请参考以下文章

为啥我们需要 C++ 中的纯虚析构函数?

c++中的纯虚函数机制如何从DLL中暴露函数

C++ 子函数中的纯虚函数和未使用的参数

C++中重载加减乘除等运算符的纯虚函数中的返回类型怎么定义??运算符中参数怎么写??

C++纯虚函数和抽象类

带有实现的纯虚函数