Question

I would like to pose the following design pattern to discussion. It implements a universal "getMany" method in the base class that uses a given get-method from the derived class to get many entities (here for simplification of explicit type int). This means that any derived class has to inform the "getMany" method which get-method to use. This is a case of calling a pointer-to-member function in a derived class from the base class.

What I would like to pose to discussion: what alternative, easier patterns to achieve the same can you think of?

Thank you!

P.S.: As noted above in a real case one would of course abstract the fixed type "int" to a template type T. P.P.S.: predefining the get-methods as virtual methods in the base class did not seem a good option, since it would restrict the number of and naming of the 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;
}
Was it helpful?

Solution

Here is an example using function objects.

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++ );
        }
    }
};

With this, client code can call getMany using lambdas (c++11) or create their own function objects.

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

OTHER TIPS

You can just use regular polymorphism here. Have an abstract method that you call via the this pointer from the base class method. A simplified example is:

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();
}

I hope that gives you the basic idea.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top