如何调用存储在基类中的虚方法,并由一个继承该基类两次的类调用?

问题描述 投票:0回答:1

此代码演示了此问题:

class Base
{
public:
    explicit Base(std::function<void()> const& printFunc) :
        _printFunc(printFunc)
    {
    }

    void print()
    {
        _printFunc();
    }
private:
   std::function<void()> _printFunc{};
private:
    virtual void _print() = 0; // If this line is commented out, then 
                               // `Subclass1::_print()` can be called.
};

class Subclass1 : public Base
{
public:
    explicit Subclass1() :
        Base([this]() { _print(); })
    {
    }
private:
    void _print() /*override*/
    {
        std::cout << "Subclass1\n";
    }
};

class Subclass2 : public Base, public Subclass1
{
public:
    using fromLowestSubclass = Base;
public:
    explicit Subclass2() :
        Base([this]() { _print(); }), Subclass1()
    {
    }
private:
    void _print() /*override*/
    {
        // Here is the problem:
        Subclass1::print(); // or: static_cast<Subclass1*>(this)->print(); 

        std::cout << "Subclass2\n";
    }
};

int main()
{
    Subclass2 sc2{};
    sc2.fromLowestSubclass::print();

    return 0;
}

Subclass2::_print方法中,应该调用_print的重写Subclass1方法,而是Subclass1::print();语句再次调用当前方法。如果语句virtual void _print() = 0;被注释掉,则可以防止此问题。 为什么使用虚拟_print方法阻止我调用重载的虚拟方法Subclass1::_print以及有什么解决方案,以便我不必没有虚拟方法?

c++ class oop multiple-inheritance
1个回答
0
投票
class Base
{
    ....
private:
    virtual void _print() = 0; 
}

这意味着:你可以覆盖_print,但你无法调用它,只有Base有权调用它。

现在:

class Base
{
public:
    void print()
    {
        _printFunc();
    }

这样做,它将_printFunc称为虚拟函数,它匹配当前对象实例化。它没有计量如何调用print()

添加Subclass1::作为前缀只会更改名称范围,并且不会影响方法的行为方式。它只对名称范围产生影响。

现在,如果虚方法有这样的前缀,那么选择名称范围指示编译器放弃抽象,你需要调用特定的方法。在这种情况下,在不参考虚拟表的情况下调用方法。

双重继承对此问题没有影响。

您可以提供一个帮助方法,您可以从祖先调用它:

class Subclass1 : public Base
{
    ....
protected:
    void sub1_print() // not virtual
    {
        std::cout << "Subclass1\n";
    }
private:
    void _print() /*override*/
    {
        sub1_print();
    }
};

class Subclass2 : public Base, public Subclass1
{
    ....
private:
    void _print() /*override*/
    {
        sub1_print();

        std::cout << "Subclass2\n";
    }
};
© www.soinside.com 2019 - 2024. All rights reserved.