如何实现纯虚函数

时间:2013-12-24 07:08:58

标签: c++ polymorphism pure-virtual

考虑以下示例

#include <iostream>

struct PureVirtual {
    virtual void Function() = 0;
};

struct FunctionImpl {
    virtual void Function() {
        std::cout << "FunctionImpl::Function()" << std::endl;
    }   
};

struct NonPureVirtual : public FunctionImpl, public PureVirtual {
    using FunctionImpl::Function;
};

int main() {
    NonPureVirtual c;
    c.Function();
}

编译器(GCC 4.9,Clang 3.5)退出时出错

test.cpp:18:20: error: variable type 'NonPureVirtual' is an abstract class
    NonPureVirtual c;
                   ^
test.cpp:4:18: note: unimplemented pure virtual method 'Function' in 'NonPureVirtual'
    virtual void Function() = 0;
             ^

但是当我没有得到形式Pure Virtual时,一切都还可以。这很奇怪,因为标准10.4.4说

  

如果包含或继承至少一个纯虚函数,则该类是抽象的,其最终覆盖为纯虚拟

他们没有说最后的覆盖是什么,但我想它应该是FunctionImpl::Function(),特别是当我通过using指令使它可用时。那么为什么仍然是非纯虚拟抽象类,我该如何解决这个问题?

3 个答案:

答案 0 :(得分:1)

FunctionImpl::FunctionPureVirtual::Function是不同类别的不同功能。

他们各自的类型是void (FunctionImpl::*)()void (PureVirtual::*)()。 由于PureVirtual和FunctionImpl是不相关的类,因此这些函数类型是不相关的。

它们碰巧具有相同的名称和相同的参数以及返回类型,但由于它们不同,因此使用FunctionImpl :: Function行并不会使该函数覆盖PureVirtual中的函数。

如果您声明了void (PureVirtual::*)()类型的变量,您将无法为其分配FunctionImpl :: Function。

换句话说,PureVirtual :: Function的最终覆盖是PureVirtual中的原始覆盖,它是纯虚拟的。

答案 1 :(得分:1)

以下源代码通过示例演示了我对虚拟继承的评论。它编译并运行良好。

#include <iostream>

struct PureVirtual {
    virtual void Function() = 0;
};

struct FunctionImpl : public virtual PureVirtual {
    virtual void Function() {
        std::cout << "FunctionImpl::Function()" << std::endl;
    }   
};

struct NonPureVirtual : public FunctionImpl, public virtual PureVirtual {
    using FunctionImpl::Function;
};

int main() {
    NonPureVirtual c;
    c.Function();
}


/*
Local Variables:
compile-command: "g++ ./test.cc"
End:
 */

答案 2 :(得分:0)

如果要从纯虚拟类派生,则需要覆盖所有纯虚函数(如果要创建类的实例)。 FunctionImplPureVirtual

完全无关

所以

struct NonPureVirtual : public FunctionImpl, public PureVirtual {
    using FunctionImpl::Function;
};

是不够的,您需要在NonPureVirtual类

中实现void Function
struct NonPureVirtual : public FunctionImpl, public PureVirtual {
    void Function() {}
};