【问题标题】:Call to non virtual function in derived class from base class (C++)从基类调用派生类中的非虚函数(C++)
【发布时间】:2020-06-06 17:20:28
【问题描述】:

test 不是虚函数,在基类和派生类中都定义了。 我有一个派生类对象。它最终调用基类的test,而不是派生类中的test。 为什么会这样? 如何设置它以便根据对象类型调用测试。

当前的o/p

B func                                                                                                         
A f1                                                                                                           
A test

我希望它是

B func                                                                                                         
A f1                                                                                                           
B test
#include <iostream>

using namespace std;
class A {
    protected:
    void test()
    {
        cout<<"A test"<<endl;
    }
    void f1(){
        cout<<"A f1" <<endl;
        test();
    }
};
class B: public A {
    protected: 
    void test()
    {
        cout<<"B test" <<endl;
    }
   public:
    void func(){
        cout<<"B func" << endl;
        f1();

    }

};
int main()
{
    B tmp;
    tmp.func();
    return 0;
}

【问题讨论】:

  • 在这种情况下,您需要将功能测试虚拟化。
  • 你从A的成员调用test,所以它会调用testA版本因为它不是一个虚函数。这就是virtual 所做的。
  • 有些情况下,我想在从基类 A 的对象访问时在 A 中调用 test。f1 有没有办法根据对象调用 test?使测试虚拟化似乎有效!如果虚函数在基类中有定义,是否有任何副作用/警告。

标签: c++ inheritance


【解决方案1】:

有两种方法可以归档所需的结果:

使用virtual
将基类函数声明为虚拟函数将确保默认调用目标函数的最高继承。例如,在您的情况下:

class A {
protected:

    /**
     * Declared also in the derived class, so as long the current object is the derived class,
     * this function will be called from the derived class.
     * [Enabled only due to the use of the `virtual` keyword].
     */
    virtual void test() {
        cout << "A test" << endl;
    }

    void f1() {
        cout << "A f1" << endl;
        test();
    }
};

使用 CRTP [巨大的开销来存档可以使用虚拟存档的内容]

template <class Derived> // Template param that will accept the derived class that inherit from this class.
class A {
protected:
    virtual void test() const {
        cout << "A test" << endl;
    }

    void f1() const {
        cout << "A f1" << endl;
        static_cast<Derived const&>(*this).test(); // Call test() function from the derived class.
    }
};

class B: public A<B> { // inherit A that accepts template argument this derived class
// protected:
public: // Pay attention that now test should be public in the derived class in order to access it via the base class.
    void test() const override {
        cout << "B test" << endl;
    }

//public:
    void func() const {
        cout << "B func" << endl;
        f1();
    }
};

Read more about CRTP.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-16
    • 1970-01-01
    • 2011-09-27
    • 1970-01-01
    • 2021-05-09
    • 2019-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多