【问题标题】:Can I overload pure virtual method in the base class?我可以在基类中重载纯虚方法吗?
【发布时间】:2015-06-18 03:44:11
【问题描述】:

在下面的示例中,我有一个带有纯虚方法(又名 FUN1)和普通方法(又名 FUN2)的抽象类。

#include <iostream>

class A
{
public:
        virtual void fun(int i) = 0; // FUN1
        void fun() { this->fun(123); } // FUN2
};

class B : public A
{
public:
        virtual void fun(int i) { std::cerr << i << std::endl; }
};

int main(int,char**)
{
        B b;
        b.fun();
}

为什么我不能在派生类上调用 FUN2? g++ 报错:

main.cpp:19:8: 错误:没有匹配函数调用‘B::fun()’


编辑:注意Overload of pure virtual function 的问题是不同的。我不想覆盖方法。

【问题讨论】:

标签: c++ inheritance interface


【解决方案1】:

这就是派生类成员查找的工作原理:在表达式b.fun() 中,首先在class B 的范围内查找fun,然后查找找到B::fun(int)。所以它停止并且永远找不到A::fun()

标准的相关部分是10.2 [class.member.lookup]/4:

如果C 包含名称为f 的声明,则声明集包含f 中声明的每个声明 C 满足查找发生的语言结构的要求。 (...)如果结果声明集不为空,则子对象集包含C本身,计算完成。

要使基类函数可以直接访问,您可以在派生类中使用using 声明,即using A::fun;

对于在基类中实现的方法,有时另一种方法是有资格调用,即b.A::fun()

【讨论】:

    【解决方案2】:

    尝试在B类中添加using A::fun;语句:

    #include <iostream>
    
    class A
    {
    public:
        virtual void fun(int i) = 0; // FUN1
        void fun() { this->fun(123); } // FUN2
    };
    
    class B : public A
    {
    public:
        using A::fun;
        virtual void fun(int i) { std::cerr << i << std::endl; }
    };
    
    int main(int, char**)
    {
        B b;
        b.fun();
        b.fun(5);
    }
    

    【讨论】:

    • 但我为什么需要它?
    • @user2449761 由于fun() 未声明为virtual,因此必须在派生类中显式引入。
    • 请注意,virtual 在这里是一个红鲱鱼。在 B 中定义一些函数 foo 会从基类中隐藏函数 foo,除非您显式导入它们。
    猜你喜欢
    • 1970-01-01
    • 2014-09-20
    • 1970-01-01
    • 2019-07-16
    • 1970-01-01
    • 2018-08-01
    • 2019-02-07
    • 2017-05-24
    相关资源
    最近更新 更多