【问题标题】:Why does implementation of abstract class not see overloaded pure virtual function?为什么抽象类的实现看不到重载的纯虚函数?
【发布时间】:2013-04-20 23:50:41
【问题描述】:

鉴于以下代码示例,为什么重载的AbstractBaseClass::DoAThing( const char* ) 在实现重载的纯抽象DoAThing( const char* const* ) 方法的SomeEndClass 中作为继承方法不可见?

class AbstractBaseClass
{
    public:

        virtual void DoAThing( const char* withThis ) {}
        virtual void DoAThing( const char* const* withThat ) = 0;

        AbstractBaseClass() {}
        virtual ~AbstractBaseClass() {}
};

class SomeMiddlewareClass : public AbstractBaseClass
{
    public:

        void ThisIsCool() {}

        SomeMiddlewareClass() {}
        virtual ~SomeMiddlewareClass() {}
};

class SomeEndClass : public SomeMiddlewareClass
{
    public:

        void DoAThing( const char* const* withThat ) {}

        SomeEndClass() {}
        virtual ~SomeEndClass() {}
};

void SomeFunction()
{
    SomeEndClass* myClass = new SomeEndClass();

    myClass->DoAThing( "withThis" );
    ((SomeMiddlewareClass*)myClass)->DoAThing( "withThisToo" );

    delete myClass;
}

编译器(和索引器)在myClass->DoAThing( "withThis" ); 行产生以下错误,而((SomeMiddlewareClass*)myClass)->DoAThing( "withThisToo" ); 行被接受。

Invalid arguments ' 候选者是:void DoAThing(const char * const *)

没有匹配函数调用‘SomeEndClass::DoAThing(const char [9])’

SomeEndClass 不应该继承AbstractBaseClass::DoAThing( const char* ) 的实现吗?我做错了什么?

【问题讨论】:

  • 这两个虚函数都必须实现。他们不是。

标签: c++ inheritance abstract-class pure-virtual


【解决方案1】:

您的SomeEndClass::DoAThing() 函数不仅覆盖从基类继承的函数,而且隐藏该函数在基类中的其他重载。

您可以在 SomeEndClass 类中添加 using 声明:

using SomeMiddlewareClass::DoAThing;

因此:

class SomeEndClass : public SomeMiddlewareClass
{
    public:

        using SomeMiddlewareClass::DoAThing;
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

        void DoAThing( const char* const* withThat ) {}

        SomeEndClass() {}
        virtual ~SomeEndClass() {}
};

通过此修复,您可以在 live example 中看到您的程序正在编译。

【讨论】:

  • 谢谢。选择从谁那里接受答案是一个挑战......但既然你是第一次遇到输入键〜微笑〜感谢@Jerry Coffin。
  • @KScottPiel:好的,很高兴它有帮助:)
  • 有趣。无论出于何种原因,除非我使用 using AbstractBaseClass::DoAThing;,否则我的工具链(Apple LLVM 版本 4.2 (clang-425.0.27))不会吃掉这个
  • @WhozCraig:很有趣。它是否抱怨using 声明?错误信息是什么?
  • 它抱怨main() 中的用法,而不是类decl。我只是想通了为什么。与 OP 的代码不同,我在中间件类中重新声明了 void DoAThing( const char* const* withThat ) = 0;(习惯,我总是将任何继承的纯虚拟实现或重新声明为纯)。删除 re-decl 允许你的中间件 using 子句工作,否则它可以与 Jerry 的基类 using 子句一起工作。
【解决方案2】:

在您的基类中,DoAThing 不仅是虚拟的,而且是重载的。

派生类中的函数覆盖其中一个重载并隐藏另一个。

然后你试图呼叫另一个,它是隐藏的。

您可以使用using 声明使隐藏函数在派生类中可见:

using Base::DoAThing;

...但你是否应该是一个单独的(更复杂的)问题。

【讨论】:

    猜你喜欢
    • 2014-10-21
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    • 2019-12-08
    • 1970-01-01
    • 2016-02-18
    • 2013-01-15
    • 2016-11-16
    相关资源
    最近更新 更多