Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > static polymorphism and Factory Pattern

Reply
Thread Tools

static polymorphism and Factory Pattern

 
 
alexander.stippler@uni-ulm.de
Guest
Posts: n/a
 
      07-26-2006
Hello,

I need on the one hand static polymorphism for efficiency concerns,
e.g.

template <typename P>
class Problem
{
public:
const P &
problem() const { return static_cast<const P &>(*this); }

P &
problem() { return static_cast<P &>(*this); }

void
method1() { this->problem().method1(); }

// .... other methods
};

template <typename T>
class SpecificProblem
: public Problem<SpecificProblem<T> >
{
public:
void
method1() {}
};

There is one specific interface all derived classes have to share, so
this CRTP-method is well suited.
But I also want the following: Which specific problem I have to
instantiate is given by some external run-time value, let's say by a
string. Ok, so I could use the Factory pattern for instatiation. But
for this pattern I need some common base class as return type for the
created object. Let us for the moment consider we have this type
'ProblemType *' (it cannot be 'Problem *'!). There is no way back such
that I could use the structure above, i.e. call 'method1()' efficiently
(or at all). Any solutions.
I need:
several classes all sharing a common interface.
a method like factory pattern to instantiate the classes given a
'string value'
efficient usage of the class's methods afterwards (no virtual
function calls!)
I fear, that's too many requirements to fulfill at the same time.

Best regards,
Alex

 
Reply With Quote
 
 
 
 
Josh Mcfarlane
Guest
Posts: n/a
 
      07-26-2006

http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> I need:
> several classes all sharing a common interface.
> a method like factory pattern to instantiate the classes given a
> 'string value'
> efficient usage of the class's methods afterwards (no virtual
> function calls!)
> I fear, that's too many requirements to fulfill at the same time.


Why can you not make a virtual function call?

Josh McFarlane

 
Reply With Quote
 
 
 
 
alexander.stippler@uni-ulm.de
Guest
Posts: n/a
 
      07-26-2006

Josh Mcfarlane schrieb:

> (E-Mail Removed) wrote:
> > I need:
> > several classes all sharing a common interface.
> > a method like factory pattern to instantiate the classes given a
> > 'string value'
> > efficient usage of the class's methods afterwards (no virtual
> > function calls!)
> > I fear, that's too many requirements to fulfill at the same time.

>
> Why can you not make a virtual function call?
>
> Josh McFarlane


because the functions are very simple, called thousands of times and
the virtual function overhead would be performance critical.

 
Reply With Quote
 
BigBrian
Guest
Posts: n/a
 
      07-26-2006

(E-Mail Removed) wrote:
> because the functions are very simple, called thousands of times and
> the virtual function overhead would be performance critical.


It seems most people who make this claim do so on their belief and not
on fact. Have you tested your statement by actual measurement?

Usually, if you eliminate the polymorphism, you will end up with a
switch statement in your code. For efficiency, both are about the
same. But using virtual functions will produce code that is cleaner
and easier to maintain and extend.

-Brian

 
Reply With Quote
 
Arne Adams
Guest
Posts: n/a
 
      07-26-2006

<(E-Mail Removed)> schrieb im Newsbeitrag
news:(E-Mail Removed) oups.com...
> Hello,
>
> I need on the one hand static polymorphism for efficiency concerns,
> But I also want the following: Which specific problem I have to
> instantiate is given by some external run-time value, let's say by a
> string.


If you could put the creation and the handling of the problem into 1
function it could be done like this:
(But it is no longer evident what the Baseclass Problem<T> is for)

#include <map>
#include <string>


template <typename P>
class Problem
{
public:
const P &
problem() const { return static_cast<const P &>(*this); }

P &
problem() { return static_cast<P &>(*this); }

void
method1() { this->problem().method1(); }

// .... other methods
};

template <typename T>
class SpecificProblem
: public Problem<SpecificProblem<T> >
{
public:
void method1() {}
};

typedef void (*CreateAndSolveFunction)();

template<typename P> void Solve(Problem<P>& trouble)
{
trouble.method1();
}

template<typename ConcreteTrouble> void DoCreateAndSolve()
{
SpecificProblem<ConcreteTrouble> concreteTrouble;
Solve(concreteTrouble);
}

typedef std::map<std::string, CreateAndSolveFunction> SolvableProblems;

SolvableProblems InitSolvableProblems()
{
SolvableProblems result;
result[std::string("int")]=&DoCreateAndSolve<int>;
return result;
}

void CreateAndSolve(std::string const& problemId)
{
static const SolvableProblems solvableProblems = InitSolvableProblems();
SolvableProblems::const_iterator where =
solvableProblems.find(problemId);
if(where != solvableProblems.end())
(*where->second)();
}

int main()
{
CreateAndSolve("int");
}

Regards,
Arne


 
Reply With Quote
 
alexander.stippler@uni-ulm.de
Guest
Posts: n/a
 
      07-26-2006

BigBrian schrieb:

> (E-Mail Removed) wrote:
> > because the functions are very simple, called thousands of times and
> > the virtual function overhead would be performance critical.

>
> It seems most people who make this claim do so on their belief and not
> on fact. Have you tested your statement by actual measurement?
>


Yes. I have.

> Usually, if you eliminate the polymorphism, you will end up with a
> switch statement in your code. For efficiency, both are about the
> same. But using virtual functions will produce code that is cleaner
> and easier to maintain and extend.
>
> -Brian


I do not see how my polymorphism problem can be mapped to switch
statements. You mean a switch depending on the type? If yes, what does
this have to do with my problem?

 
Reply With Quote
 
alexander.stippler@uni-ulm.de
Guest
Posts: n/a
 
      07-27-2006

Arne Adams schrieb:

> <(E-Mail Removed)> schrieb im Newsbeitrag
> news:(E-Mail Removed) oups.com...
> > Hello,
> >
> > I need on the one hand static polymorphism for efficiency concerns,
> > But I also want the following: Which specific problem I have to
> > instantiate is given by some external run-time value, let's say by a
> > string.

>
> If you could put the creation and the handling of the problem into 1
> function it could be done like this:
> (But it is no longer evident what the Baseclass Problem<T> is for)
>
> #include <map>
> #include <string>
>
>
> template <typename P>
> class Problem
> {
> public:
> const P &
> problem() const { return static_cast<const P &>(*this); }
>
> P &
> problem() { return static_cast<P &>(*this); }
>
> void
> method1() { this->problem().method1(); }
>
> // .... other methods
> };
>
> template <typename T>
> class SpecificProblem
> : public Problem<SpecificProblem<T> >
> {
> public:
> void method1() {}
> };
>
> typedef void (*CreateAndSolveFunction)();
>
> template<typename P> void Solve(Problem<P>& trouble)
> {
> trouble.method1();
> }
>
> template<typename ConcreteTrouble> void DoCreateAndSolve()
> {
> SpecificProblem<ConcreteTrouble> concreteTrouble;
> Solve(concreteTrouble);
> }
>
> typedef std::map<std::string, CreateAndSolveFunction> SolvableProblems;
>
> SolvableProblems InitSolvableProblems()
> {
> SolvableProblems result;
> result[std::string("int")]=&DoCreateAndSolve<int>;
> return result;
> }
>
> void CreateAndSolve(std::string const& problemId)
> {
> static const SolvableProblems solvableProblems = InitSolvableProblems();
> SolvableProblems::const_iterator where =
> solvableProblems.find(problemId);
> if(where != solvableProblems.end())
> (*where->second)();
> }
>
> int main()
> {
> CreateAndSolve("int");
> }
>
> Regards,
> Arne


Thanks for your idea. You never have to deal with the concrete
Problem's type at all. Clever. But unfortunately this is not enough in
my situation. I have to be able to pass the ConcreteProblem to
functions as argument. I just considered if virtual functions are
really that evil to my problem, test it and they are!! So I perhaps
have to think about completely different approaches.

Alex

 
Reply With Quote
 
Arne Adams
Guest
Posts: n/a
 
      07-27-2006
Hi,


<(E-Mail Removed)> schrieb im Newsbeitrag
news:(E-Mail Removed) ups.com...
>
> Arne Adams schrieb:
>
>> template<typename P> void Solve(Problem<P>& trouble)
>> {
>> trouble.method1();
>> }
>>
>> template<typename ConcreteTrouble> void DoCreateAndSolve()
>> {
>> SpecificProblem<ConcreteTrouble> concreteTrouble;
>> Solve(concreteTrouble);
>> }
>>

>
> Thanks for your idea. You never have to deal with the concrete
> Problem's type at all. Clever. But unfortunately this is not enough in
> my situation. I have to be able to pass the ConcreteProblem to
> functions as argument.


Could you post code for what you need to do?

Note that Solve could as well operate directly on the most derived problem
type because Solve is called in a context where that type is statically
known.

Arne


 
Reply With Quote
 
alexander.stippler@uni-ulm.de
Guest
Posts: n/a
 
      07-27-2006

Arne Adams schrieb:

> Hi,
>
>
> <(E-Mail Removed)> schrieb im Newsbeitrag
> news:(E-Mail Removed) ups.com...
> >
> > Arne Adams schrieb:
> >
> >> template<typename P> void Solve(Problem<P>& trouble)
> >> {
> >> trouble.method1();
> >> }
> >>
> >> template<typename ConcreteTrouble> void DoCreateAndSolve()
> >> {
> >> SpecificProblem<ConcreteTrouble> concreteTrouble;
> >> Solve(concreteTrouble);
> >> }
> >>

> >
> > Thanks for your idea. You never have to deal with the concrete
> > Problem's type at all. Clever. But unfortunately this is not enough in
> > my situation. I have to be able to pass the ConcreteProblem to
> > functions as argument.

>
> Could you post code for what you need to do?
>
> Note that Solve could as well operate directly on the most derived problem
> type because Solve is called in a context where that type is statically
> known.
>
> Arne


OK. I think code wold be too lengthy. The concept:
- a library providing mainly a special kind of 'Solver'. As input it
needs some
'Problem' given by a) a descrition file (several parameters)
and b) a realization of a class
'SpecificProblem' implementing some methods
which are to be called by the Solver
instantiation and are
problem specific (very frequently
called).
- which specific realization of Problem shoud be used is given by a
string in the description file.
- the main 'Solver' class should be able to pass its argument - the
SpecificProblem - to other
parts implementing the Solver ingredients.

I tend to think, that the CRTP is the thing one could perhaps replace.
The need for efficient function calls for the SpecificProblem is
perhaps easier to fulfill than the combination of CRTP and Factory
methods. Keeping the factory approach one then has to find a way for
efficient realizations of SpecificProblem.

Alex

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Abstract factory and Factory pattern C# ASP .Net 4 07-31-2008 03:22 PM
Design problem: Factory pattern needs 'static virtual'? Markus Dehmann C++ 2 01-04-2008 09:11 AM
documents related to factory design pattern and Abstract foctory pattern. sunny C++ 1 12-07-2006 04:26 AM
Dynamic polymorphism vs. Static polymorphism Krivenok Dmitry C++ 13 06-01-2006 09:49 AM
Abstract Factory or Factory Method pattern question.... Medi Montaseri C++ 17 09-03-2003 06:50 AM



Advertisments