【问题标题】:How to implement pure virtual function如何实现纯虚函数
【发布时间】:2013-12-24 07:08:58
【问题描述】:

考虑下面的例子

#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 说

一个类是抽象的,如果它包含或继承至少一个纯虚函数,其最终覆盖者是纯虚。 p>

他们并没有说明最终的替代者是什么,但我想它应该是FunctionImpl::Function(),尤其是当我通过 using 指令使其可用时。那么为什么仍然是 Non Pure Virtual 抽象类,我该如何解决这个问题?

【问题讨论】:

  • 您似乎将 c++ 与 Java 混淆了。仅仅因为 FunctionImpl 和 PureVirtual 都具有相同签名的方法并不能使一个成为另一个的实现。
  • 我认为这是一个较大程序的摘录,实际问题可能如下:如果您不想将 PureVirtual 作为基类的两倍,则必须从它继承实际上(public virtual PublicVirtual)。 (谷歌的“虚拟继承”。)

标签: c++ polymorphism pure-virtual


【解决方案1】:

FunctionImpl::FunctionPureVirtual::Function 是不同类的不同函数。

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

它们恰好具有相同的名称、相同的参数和返回类型,但由于它们不同,因此 using FunctionImpl::Function 行不会使该函数覆盖 PureVirtual 中的函数。

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

也就是说,PureVirtual::Function 的最终覆盖是 PureVirtual 中原来的那个,是纯虚的。

【讨论】:

    【解决方案2】:

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

    #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:
     */
    

    【讨论】:

      【解决方案3】:

      从纯虚类派生时,如果要创建该类的实例,则需要覆盖所有纯虚函数。 FunctionImplPureVirtual 完全无关

      所以

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

      还不够,还需要在类NonPureVirtual中实现void函数

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

      【讨论】:

        猜你喜欢
        • 2016-03-07
        • 1970-01-01
        • 2016-02-18
        • 2021-10-26
        • 2013-12-31
        • 2011-01-06
        • 1970-01-01
        相关资源
        最近更新 更多