473,386 Members | 1,644 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

static polymorphism and Factory Pattern

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

Jul 26 '06 #1
8 3118

al****************@uni-ulm.de 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

Jul 26 '06 #2

Josh Mcfarlane schrieb:
al****************@uni-ulm.de 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.

Jul 26 '06 #3

al****************@uni-ulm.de 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

Jul 26 '06 #4

<al****************@uni-ulm.deschrieb im Newsbeitrag
news:11**********************@m79g2000cwm.googlegr 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<Tis 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 Pvoid Solve(Problem<P>& trouble)
{
trouble.method1();
}

template<typename ConcreteTroublevoid DoCreateAndSolve()
{
SpecificProblem<ConcreteTroubleconcreteTrouble;
Solve(concreteTrouble);
}

typedef std::map<std::string, CreateAndSolveFunctionSolvableProblems;

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
Jul 26 '06 #5

BigBrian schrieb:
al****************@uni-ulm.de 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?

Jul 26 '06 #6

Arne Adams schrieb:
<al****************@uni-ulm.deschrieb im Newsbeitrag
news:11**********************@m79g2000cwm.googlegr 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<Tis 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 Pvoid Solve(Problem<P>& trouble)
{
trouble.method1();
}

template<typename ConcreteTroublevoid DoCreateAndSolve()
{
SpecificProblem<ConcreteTroubleconcreteTrouble;
Solve(concreteTrouble);
}

typedef std::map<std::string, CreateAndSolveFunctionSolvableProblems;

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

Jul 27 '06 #7
Hi,
<al****************@uni-ulm.deschrieb im Newsbeitrag
news:11*********************@m79g2000cwm.googlegro ups.com...
>
Arne Adams schrieb:
>template<typename Pvoid Solve(Problem<P>& trouble)
{
trouble.method1();
}

template<typename ConcreteTroublevoid DoCreateAndSolve()
{
SpecificProblem<ConcreteTroubleconcreteTrouble;
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
Jul 27 '06 #8

Arne Adams schrieb:
Hi,
<al****************@uni-ulm.deschrieb im Newsbeitrag
news:11*********************@m79g2000cwm.googlegro ups.com...

Arne Adams schrieb:
template<typename Pvoid Solve(Problem<P>& trouble)
{
trouble.method1();
}

template<typename ConcreteTroublevoid DoCreateAndSolve()
{
SpecificProblem<ConcreteTroubleconcreteTrouble;
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

Jul 27 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: javac | last post by:
for better or worse, my free time is consumed by two Java series books from Sun: Java Platform Performance, 2000, by Wilson and Kesselman Effective Java, 2001, by Bloch 1.) opinions on these...
5
by: shablool | last post by:
Hi all, Could someone please explain what is wrong with this code (the compiler complains about "'int_type' is not a member of 'B'"): struct B; template <typename DerivedT> struct A {
4
by: PengYu.UT | last post by:
Hi, Some dynamic polymorphism programs can be converted to the equavalent static polymorphism programs. I'm wondering if there are any generall procedures that I can use to do this conversion. ...
33
by: Chris Capel | last post by:
What is the rationale behind the decision not to allow abstract static class members? It doesn't seem like it's a logically contradictory concept, or that the implementation would be difficult or...
15
by: rwf_20 | last post by:
I just wanted to throw this up here in case anyone smarter than me has a suggestion/workaround: Problem: I have a classic producer/consumer system which accepts 'commands' from a socket and...
18
by: Seigfried | last post by:
I have to write a paper about object oriented programming and I'm doing some reading to make sure I understand it. In a book I'm reading, however, polymorphism is defined as: "the ability of two...
5
by: Dinsdale | last post by:
I was discussing class architecture with one of the senior developers at my new job and him and I have a similar idea on how to work with data access and class libraries. That said, our...
6
by: newbie | last post by:
class AbstractBook { public: virtual static AbstractBook* Allocate () =0; virtual PrintTitle() = 0; } class ScifiBook { public: static AbstractBook* Allocate () { return new ScifiBook; }...
2
by: Markus Dehmann | last post by:
I need a simple object serialization, where loading an object from file looks like this: Foo* foo1 = FooFactory::create("./saved/foo1.a321f23d"); Foo* foo2 =...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.