2014-02-06 47 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方法的数量和命名。 –

相关问题