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

时间:2011-10-03 19:04:55

标签: c++ oop stl

嗨,假设我有这样的代码

// 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。

谢谢

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

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

无论如何,这符合(我的解释)您从基类调用函数的要求,这些函数根据实际派生类而不使用虚函数而表现不同。你想要使用的例子对我来说并不完全清楚。如果这种机制不能满足您的需求,请澄清需求。

#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