2011-10-03 52 views
0

嗨假设我有这样调用从基类派生类的功能,无需使用虚拟函数

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

感谢

+0

[CRTP(https://secure.wikimedia.org/wikipedia/en/wiki/Curiously_recurring_template_pattern)可以帮助 – rlduffy

回答

2

你必须定义被称为static的功能,并提供额外的参数传递给他们的对象实例(而不是this,如果称为普通成员函数,他们会得到)。

+0

感谢..我想到了这一点,而这个工程,但如果我不希望使用静态比它可能吗? –

+0

这不是微不足道的,因为这些类是相关的。对于不相关的类(其中一个的定义不依赖于另一个的定义,你可以直接使用)。你可以做的是传递原始指针,并将它们投射到实现类A的单独文件中的B :: function指针中。这很丑陋,我不会那样做(我不会做你在做的事情所有的,它的设计不好) – littleadv

+0

嗯..是的,你对错误的设计是正确的,实际上我只是在学习STL,当我了解mem_fun时,我认为这种事情是可能的,显然不是。 –

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 
相关问题