我想提出以下设计模式进行讨论。它在基类中实现了一个通用的“getMany”方法,该方法使用派生类中的给定get方法来获取许多实体(这里是为了简化显式类型int)。这意味着任何派生类都必须通知“getMany”方法使用哪个get-method。这是从基类调用派生类中的指向成员函数的情况。
我想讨论的内容:你能想到什么样的替代方案,更容易实现的模式?
谢谢!
P.S。:如上所述,在实际案例中,当然会将固定类型“int”抽象为模板类型T. P.P.S:将get方法预定义为基类中的虚方法似乎不是一个好的选择,因为它会限制get方法的数量和命名。
#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;
}
答案 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++ );
}
}
};
有了这个,客户端代码可以使用lambdas(c ++ 11)调用getMany或创建自己的函数对象。
auto callMoo = [this] (char i) { return Moo(i); };
getMany(callMoo, n);
答案 1 :(得分: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();
}
我希望这能为您提供基本的想法。