2014-02-06 46 views
1

我想提出以下設計模式來討論。它在基類中實現了一個通用的「getMany」方法,該方法使用派生類中的給定get方法獲取許多實體(這裏用於簡化顯式類型int)。這意味着任何派生類都必須通知「getMany」方法使用哪個get-method。這是在基類的派生類中調用指向成員函數的一個例子。C++通過基類派生類中的指針成員函數調用

我想提出的討論:什麼替代方案,更容易實現相同的模式可以想到?

謝謝!

PS:如上所述,在真實情況下,人們當然會將固定類型「int」抽象爲模板類型T.PPS:預定義get-methods作爲基類中的虛擬方法似乎不是一個好東西選項,因爲它會限制get-methods的數量和命名。

#include <iostream> 
#include <memory> 
#include <algorithm> 
#include <vector> 

using namespace std; 

// EXAMPLE FOR CALL VIA POINTER TO OVERLOADED METHOD IN DERIVED CLASS FROM BASE CLASS 

class FooBase 
{ 
    public: 

    template<class PCLASS> 
    std::vector<int> getMany(int (PCLASS::*getEnt)(int) const, int n, const PCLASS *pClass) const 
    { 
     std::vector<int> e; 
     int i = 0; 
     e.resize(n); 

     for (std::vector<int>::iterator it = e.begin(); it!=e.end(); ++it) { 
      *it = (pClass->*getEnt)(i++); 
     } 

     return e; 
    }; 
}; 


class Foo : public FooBase 
{ 
    public: 

    int Moo(int a) const 
    { 
     return a; 
    }; 

    int Moo(char a) const 
    { 
     return (int)a; 
    }; 

    std::vector<int> Moos(int n) const 
    { 
     int (Foo::*f)(int)const; 
     f = &Foo::Moo; 

     return getMany<Foo>(f, n, this); 
    }; 

}; 

int main(int argc, char **args) 
{ 
    Foo* myFoo = new Foo(); 
    std::vector<int> res = myFoo->Moos(10); 

    for (std::vector<int>::iterator it = res.begin(); it!=res.end(); ++it) {  
     std::cout << *it; 
    } 

    return 1; 
} 
+1

在C++ 11中? std :: function和lambdas。否則好的舊功能對象。 –

+0

謝謝,能否詳細說一下?你如何將成員函數「Moo」傳遞給基類方法「getMany」? –

+0

我會這樣做的答案。 –

回答

2

這是一個使用函數對象的例子。

class FooBase 
{ 
public: 
    template< typename FunctorType > 
    std::vector<int> getMany(FunctorType const & functor, int n) 
    { 
     std::vector<int> e; 
     int i = 0; 
     e.resize(n); 

     for (std::vector<int>::iterator it = e.begin(); it!=e.end(); ++it) { 
      *it = functor(i++); 
     } 
    } 
}; 

由此,客戶端代碼可以使用getMany的lambda(C++ 11)或創建他們自己的函數對象調用。

auto callMoo = [this] (char i) { return Moo(i); }; 
getMany(callMoo, n); 
+0

謝謝,這很好!不過:你的代碼缺少一個重要的部分,「」。那就是「getMany(callMoo,n);」應該是「getMany (callMoo,n);」。請糾正這對未來的讀者.. –

+1

你確定嗎?應該很容易推導出模板參數。 –

+0

哈,你說得對!據推測,沒有指望gcc來完成這個:) –

1

您可以在這裏使用常規多態性。有一個抽象方法,您可以通過基類方法的指針this調用。一個簡單的例子是:

class FooBase 
{ 
public: 
    virtual void abstractCall() = 0; // pure virtual function, could make protected if you wanted 
    void baseMethod() 
    { 
     this->abstractCall(); // MUST use the this pointer, not a "." call 
    } 
}; 

class FooDerived : public FooBase 
{ 
public: 
    virtual void abstractCall() 
    { 
     cout << "my concrete call!" << endl; 
    } 
}; 

void bar() 
{ 
    FooDerived test; 
    test.baseMethod(); 
} 

我希望能給你基本的想法。

+0

非常感謝你的建議! 這是我的問題:我使用的基類應該被許多不同的派生類繼承。因此,將get-methods預定義爲基類中的虛擬方法似乎不是一個好的選擇,因爲它會限制get方法的數量和命名。 –

相關問題