2011-10-03 105 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 
相關問題