从基类调用派生类函数而不使用虚函数

Calling derived class function from base class Without using virtual functions

本文关键字:函数 基类 调用 派生 类函数      更新时间:2023-10-16

假设我有这样的代码

// base class                                                                                                                                                
    class A {
    public:
      int CallMyFct(PtrToFCT what){
        return what(10);
      }
    };
    class B : public A {
      int myInt;
    public:
      B():myInt(10){}
      int myFct1(int val){
        return myInt+val;
      }
      int myFct2(int val){
        return myInt*2+val;
      }

      void Call(void){
        int rez1=CallMyFct(&myFct1);
        if (rez1!=20)
          cout << "You are wrong" << endl;
        int rez2=CallMyFct(&myFct2);
        if (rez2!=30)
          cout << "You are wrong" << endl;
      }
    };

现在我需要从基类调用这些MyFct1, MyFct2等,但我不能使用虚函数。这有点像逆向继承。我不知道这是否可能。您认为mem_fun或任何其他适配器函数可以在这里工作吗?

我实际上需要弄清楚PtrToFCT是什么,以及我如何在CallMyFCT中传递myFct1。

谢谢

您必须将要调用的函数定义为static,并提供额外的参数将它们传递给对象实例(而不是作为常规成员函数调用时它们将获得的this)。

您可以使用[boost::function<>] 1更干净地做您喜欢的事情,也称为<functional>在c++ 2011中的std::function。你没有说明为什么不能使用虚函数。目前还不清楚这种方法是否比虚拟函数提供了性能增强,但是还有其他不使用虚拟函数的原因。

在任何情况下,这满足(我的解释)您的需求,从基类调用函数的行为不同取决于实际派生类,而不使用虚函数。你的理想用途的例子对我来说不是很清楚。如果此机制不能满足您的需求,请明确需求。

#include <iostream> 
#include <boost/bind.hpp>
#include <boost/function.hpp>
class A{
protected:
    typedef boost::function<int (int)> CallbackFunc;
    // A knows it can call *something* with a particular signature
    // but what is called can be overridden by the derived class.
    CallbackFunc m_callbackFunc;
public:
    A()  
    {
    m_callbackFunc = boost::bind(&A::same,this,_1); 
    } 
    int same(int val) const { return val; }
    int simulateVirtual(int val) const { return m_callbackFunc(val); }
}; //end class A
class B : public A {
    int m_offset;
public:
    B(int offset) : m_offset(offset) {
        m_callbackFunc = boost::bind(&B::offset,this,_1);
    }
    int offset(int val) const { return m_offset + val; }
}; // end class B 
int main() {
    A* pA = new A;
    A* pB = new B(42);
    std::cout << "simulateVirtual(10) called on a 'real' A instance=" 
    << pA->simulateVirtual(10) << "n";
    std::cout << "simulateVirtual(10) called via A* on a B instance="
    << pB->simulateVirtual(10) << "n";
    delete pB; // in real life I would use shared_ptr<>
    delete pA;
    return 0;
} // end main