By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,711 Members | 2,144 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,711 IT Pros & Developers. It's quick & easy.

Dynamic polymorphism vs. Static polymorphism

P: n/a
Hello all!

Perhaps the most important feature of dynamic polymorphism is
ability to handle heterogeneous collections of objects.
("C++ Templates: The Complete Guide" by David Vandevoorde
and Nicolai M. Josuttis. Chapter 14.)

How to implement analogue of this technique via static polymorphism?
Perhaps there is special design pattern for this purpose...

Thanks!

May 30 '06 #1
Share this Question
Share on Google+
13 Replies


P: n/a
Krivenok Dmitry wrote:
Hello all!

Perhaps the most important feature of dynamic polymorphism is
ability to handle heterogeneous collections of objects.
("C++ Templates: The Complete Guide" by David Vandevoorde
and Nicolai M. Josuttis. Chapter 14.)

How to implement analogue of this technique via static polymorphism?
Perhaps there is special design pattern for this purpose...

There are many concept that are called polymorphism or genericity:
http://en.wikipedia.org/wiki/Polymor...ter_science%29

Which ones do you mean (especially with "static polymorphism") exactly?
May 30 '06 #2

P: n/a
Ulrich Hobelmann wrote:
Krivenok Dmitry wrote:
Hello all!

Perhaps the most important feature of dynamic polymorphism is
ability to handle heterogeneous collections of objects.
("C++ Templates: The Complete Guide" by David Vandevoorde
and Nicolai M. Josuttis. Chapter 14.)

How to implement analogue of this technique via static polymorphism?
Perhaps there is special design pattern for this purpose...

There are many concept that are called polymorphism or genericity:
http://en.wikipedia.org/wiki/Polymor...ter_science%29

Which ones do you mean (especially with "static polymorphism") exactly?


He means C++ templates, but the question is too broad to be answered
completely here. One could implement static polymorphism like this:

struct A
{
int Read(); // Does something
};

struct B
{
int Read(); // Does something else
};

template <class T>
class Reader
{
T& t_;
public:
Reader( T& t ) : t_( t ) {}

int DoSomething()
{
return t.Read();
}
};

This template is basically the same as using an abstract base class
with a virtual Read(), but it achieves the same effect without
virtuality, which can sometimes be useful.

Cheers! --M

May 30 '06 #3

P: n/a
Krivenok Dmitry wrote:
Hello all!

Perhaps the most important feature of dynamic polymorphism is
ability to handle heterogeneous collections of objects.
("C++ Templates: The Complete Guide" by David Vandevoorde
and Nicolai M. Josuttis. Chapter 14.)

How to implement analogue of this technique via static polymorphism?
Perhaps there is special design pattern for this purpose...

Thanks!


What is the goal you are trying to accomplish?

If I had to guess, you are either trying to create some sort of compile
time container, or a run time container that supports heterogenous
types. In the former case, some variation on the type lists may be what
you want (see <url: http://www.ddj.com/dept/cpp/184403813>). In the
latter case, well, that isn't something that compile time polymorphism
can do for you. If the types you want to store have the same interface,
then use run time polymorphism. That is why it exists. If they don't,
then some form of discriminated union may do what you want.

--
Alan Johnson
May 30 '06 #4

P: n/a

mlimber wrote:
This template is basically the same as using an abstract base class
with a virtual Read(), but it achieves the same effect without
virtuality, which can sometimes be useful.


I have to debate that statement and say they are completely different.
Dynamic vs. Static polymorphism do completely different things
resulting in vastly different behavior. One simple example:

struct Abstract { virtual void f() = 0; }

struct A : Abstract { void f() {} };
struct B : Abstract { void f() {} };

void fun(Abstract * a) { a->f(); }

vs.

struct A { void f(); }
struct B { void f(); }

template <typename A>
void fun(A * a) { a->f(); }

Note how these two behave completely differently. One has a single
function that allows pointers of any of the three types to be passed in
and calls the appropriate implementation of f() for the input. The
other creates two completely different functions that accept completely
unrelated inputs; it only looks similar to the programmer. This is a
very important distinction; they are actually not the same at all.

May 30 '06 #5

P: n/a
Noah Roberts wrote:
mlimber wrote:
This template is basically the same as using an abstract base class
with a virtual Read(), but it achieves the same effect without
virtuality, which can sometimes be useful.


I have to debate that statement and say they are completely different.
Dynamic vs. Static polymorphism do completely different things
resulting in vastly different behavior. One simple example:

struct Abstract { virtual void f() = 0; }

struct A : Abstract { void f() {} };
struct B : Abstract { void f() {} };

void fun(Abstract * a) { a->f(); }

vs.

struct A { void f(); }
struct B { void f(); }

template <typename A>
void fun(A * a) { a->f(); }

Note how these two behave completely differently. One has a single
function that allows pointers of any of the three types to be passed in
and calls the appropriate implementation of f() for the input. The
other creates two completely different functions that accept completely
unrelated inputs; it only looks similar to the programmer. This is a
very important distinction; they are actually not the same at all.


I apologize for my imprecision. My point was that they are the same in
the sense that both invoke a function without knowing any further
implementation details. Certainly there are other differences between
these two types of polymorphism.

Cheers! --M

May 30 '06 #6

P: n/a

"Krivenok Dmitry" <di**@icebrains-soft.com> wrote in message
news:11*********************@i40g2000cwc.googlegro ups.com...
Hello all!

Perhaps the most important feature of dynamic polymorphism is
ability to handle heterogeneous collections of objects.
("C++ Templates: The Complete Guide" by David Vandevoorde
and Nicolai M. Josuttis. Chapter 14.)

How to implement analogue of this technique via static polymorphism?
Perhaps there is special design pattern for this purpose...

Thanks!


All elements of a container must be of the same type. If it is a pointer or
smart pointer to a common base class we have dynamic polymorphism. Static
polymorphism can be accomplished using a flag to determine the actual type:

struct clumsy
{
int flag;
union (...} other_stuff;
};

You can have an array of these but you must set the flag to the right value
for each type of data stored in the union and go through a switch or similar
logic structure every time you use it. If you want to add a new type to the
union you have to find all the logic structures and update them, so this
scheme is not very maintainable.

A variation on this theme is:

struct bummer
{
int flag;
};

struct radical
{
int flag;
double value;
};

radical r;
r.flag = 2;
r.value = 76.3;
bummer *p = (bummer*) &r;

Now you can have an array of bummer pointers, check the flag, and cast to
the actual type. This has all the problems of the union version but might
save a little memory in some cases I suppose.

Void pointers offer a sort of static polymorphism. I sometimes use them at C
interfaces where they are actually pointing to C++ classes. If you cast
carefully that can work.

Also see boost::any.

All and all when I look over these alternatives I certainly appreciate
dynamic polymorphism.

Cy
May 30 '06 #7

P: n/a
Cy Edmunds wrote:
"Krivenok Dmitry" <di**@icebrains-soft.com> wrote in message
All elements of a container must be of the same type. If it is a pointer or
smart pointer to a common base class we have dynamic polymorphism. Static
polymorphism can be accomplished using a flag to determine the actual type:

struct clumsy
{
int flag;
union (...} other_stuff;
};


Uh, I'm pretty sure this is not what most people mean by "static
polymorphism." How did you come to associate the term with this ugly
scheme?

The "static"/"dynamic" distinction wrt polymorphism, as with e.g.
typing, refers to compile-time vs. run-time. With static polymorphism,
the actual type of the object is known at compile-time. The usual
(only?) mechanism in C++ for this is templates.

Luke

May 31 '06 #8

P: n/a

"Luke Meyers" <n.***********@gmail.com> wrote in message
news:11**********************@i39g2000cwa.googlegr oups.com...
Cy Edmunds wrote:
"Krivenok Dmitry" <di**@icebrains-soft.com> wrote in message
All elements of a container must be of the same type. If it is a pointer
or
smart pointer to a common base class we have dynamic polymorphism. Static
polymorphism can be accomplished using a flag to determine the actual
type:

struct clumsy
{
int flag;
union (...} other_stuff;
};


Uh, I'm pretty sure this is not what most people mean by "static
polymorphism." How did you come to associate the term with this ugly
scheme?

The "static"/"dynamic" distinction wrt polymorphism, as with e.g.
typing, refers to compile-time vs. run-time. With static polymorphism,
the actual type of the object is known at compile-time. The usual
(only?) mechanism in C++ for this is templates.

Luke


The original poster asked about heterogeneous containers. How would you do
that with templates?

Cy

May 31 '06 #9

P: n/a

Cy Edmunds wrote:
"Luke Meyers" <n.***********@gmail.com> wrote in message
news:11**********************@i39g2000cwa.googlegr oups.com...
Cy Edmunds wrote:
"Krivenok Dmitry" <di**@icebrains-soft.com> wrote in message
All elements of a container must be of the same type. If it is a pointer
or
smart pointer to a common base class we have dynamic polymorphism. Static
polymorphism can be accomplished using a flag to determine the actual
type:

struct clumsy
{
int flag;
union (...} other_stuff;
};


Uh, I'm pretty sure this is not what most people mean by "static
polymorphism." How did you come to associate the term with this ugly
scheme?

The "static"/"dynamic" distinction wrt polymorphism, as with e.g.
typing, refers to compile-time vs. run-time. With static polymorphism,
the actual type of the object is known at compile-time. The usual
(only?) mechanism in C++ for this is templates.

Luke


The original poster asked about heterogeneous containers. How would you do
that with templates?

Check out the following example code:
http://code.axter.com/HeterogeneousContainer1.cpp
http://code.axter.com/HeterogeneousContainer2.cpp
http://code.axter.com/HeterogeneousContainer3.cpp

Each of the above files have different levels of complexity for
creating a heterogeneous container.
The basic idea is to create a wrapper class that acts like an interface
to the different types.
Although the types don't have to derive from the same object, they do
have to have a common method or common data to access.

----------------------------------------------------------------------------------------
David Maisonave
http://axter.com

Author of Axter's policy based smart pointers
(http://axter.com/smartptr)
Top ten member of C++ Expert Exchange:
http://www.experts-exchange.com/Cplusplus
----------------------------------------------------------------------------------------

May 31 '06 #10

P: n/a
Krivenok Dmitry wrote:
Perhaps the most important feature of dynamic polymorphism is
ability to handle heterogeneous collections of objects.
("C++ Templates: The Complete Guide" by David Vandevoorde
and Nicolai M. Josuttis. Chapter 14.)

How to implement analogue of this technique via static polymorphism?
Perhaps there is special design pattern for this purpose...

#include <iostream>
#include <utility>

using namespace std;
class Nil {};

template <class H, class T> int length(pair<H,T> x) {
return 1 + length(x.second);
}
int length(Nil x) { return 0; }

int main(int argc, char* argv[])
{
cout << length( make_pair(1,
make_pair(2.0,
make_pair((int[]){9,8,7},
make_pair("a string",
make_pair(true,Nil())))))) << endl;

return 0;
}

May 31 '06 #11

P: n/a

"Axter" <go****@axter.com> wrote in message
news:11**********************@h76g2000cwa.googlegr oups.com...

Cy Edmunds wrote:
"Luke Meyers" <n.***********@gmail.com> wrote in message
news:11**********************@i39g2000cwa.googlegr oups.com...
> Cy Edmunds wrote:
>> "Krivenok Dmitry" <di**@icebrains-soft.com> wrote in message
>> All elements of a container must be of the same type. If it is a
>> pointer
>> or
>> smart pointer to a common base class we have dynamic polymorphism.
>> Static
>> polymorphism can be accomplished using a flag to determine the actual
>> type:
>>
>> struct clumsy
>> {
>> int flag;
>> union (...} other_stuff;
>> };
>
> Uh, I'm pretty sure this is not what most people mean by "static
> polymorphism." How did you come to associate the term with this ugly
> scheme?
>
> The "static"/"dynamic" distinction wrt polymorphism, as with e.g.
> typing, refers to compile-time vs. run-time. With static polymorphism,
> the actual type of the object is known at compile-time. The usual
> (only?) mechanism in C++ for this is templates.
>
> Luke
>


The original poster asked about heterogeneous containers. How would you
do
that with templates?

Check out the following example code:
http://code.axter.com/HeterogeneousContainer1.cpp
http://code.axter.com/HeterogeneousContainer2.cpp
http://code.axter.com/HeterogeneousContainer3.cpp

Each of the above files have different levels of complexity for
creating a heterogeneous container.
The basic idea is to create a wrapper class that acts like an interface
to the different types.
Although the types don't have to derive from the same object, they do
have to have a common method or common data to access.

----------------------------------------------------------------------------------------
David Maisonave
http://axter.com

Author of Axter's policy based smart pointers
(http://axter.com/smartptr)
Top ten member of C++ Expert Exchange:
http://www.experts-exchange.com/Cplusplus
----------------------------------------------------------------------------------------


These are all based on dynamic polymorphism:
class Coins
{
public:
virtual int GetValue()=0;
};

Any smart pointer can function as a template based wrapper for a polymorphic
type.Cy
Jun 1 '06 #12

P: n/a

"Greg Buchholz" <sl**************@yahoo.com> wrote in message
news:11*********************@i39g2000cwa.googlegro ups.com...
Krivenok Dmitry wrote:
Perhaps the most important feature of dynamic polymorphism is
ability to handle heterogeneous collections of objects.
("C++ Templates: The Complete Guide" by David Vandevoorde
and Nicolai M. Josuttis. Chapter 14.)

How to implement analogue of this technique via static polymorphism?
Perhaps there is special design pattern for this purpose...

#include <iostream>
#include <utility>

using namespace std;
class Nil {};

template <class H, class T> int length(pair<H,T> x) {
return 1 + length(x.second);
}
int length(Nil x) { return 0; }

int main(int argc, char* argv[])
{
cout << length( make_pair(1,
make_pair(2.0,
make_pair((int[]){9,8,7},
make_pair("a string",
make_pair(true,Nil())))))) << endl;

return 0;
}


Very cool! Done any Lisp programming? hehe

Cy
Jun 1 '06 #13

P: n/a
Cy Edmunds wrote:
"Axter" <go****@axter.com> wrote in message
news:11**********************@h76g2000cwa.googlegr oups.com...

Cy Edmunds wrote:
"Luke Meyers" <n.***********@gmail.com> wrote in message
news:11**********************@i39g2000cwa.googlegr oups.com...
> Cy Edmunds wrote:
>> "Krivenok Dmitry" <di**@icebrains-soft.com> wrote in message
>> All elements of a container must be of the same type. If it is a
>> pointer
>> or
>> smart pointer to a common base class we have dynamic polymorphism.
>> Static
>> polymorphism can be accomplished using a flag to determine the actual
>> type:
>>
>> struct clumsy
>> {
>> int flag;
>> union (...} other_stuff;
>> };
>
> Uh, I'm pretty sure this is not what most people mean by "static
> polymorphism." How did you come to associate the term with this ugly
> scheme?
>
> The "static"/"dynamic" distinction wrt polymorphism, as with e.g.
> typing, refers to compile-time vs. run-time. With static polymorphism,
> the actual type of the object is known at compile-time. The usual
> (only?) mechanism in C++ for this is templates.
>
> Luke
>

The original poster asked about heterogeneous containers. How would you
do
that with templates?

Check out the following example code:
http://code.axter.com/HeterogeneousContainer1.cpp
http://code.axter.com/HeterogeneousContainer2.cpp
http://code.axter.com/HeterogeneousContainer3.cpp

Each of the above files have different levels of complexity for
creating a heterogeneous container.
The basic idea is to create a wrapper class that acts like an interface
to the different types.
Although the types don't have to derive from the same object, they do
have to have a common method or common data to access.

----------------------------------------------------------------------------------------
David Maisonave
http://axter.com

Author of Axter's policy based smart pointers
(http://axter.com/smartptr)
Top ten member of C++ Expert Exchange:
http://www.experts-exchange.com/Cplusplus
----------------------------------------------------------------------------------------


These are all based on dynamic polymorphism:
class Coins
{
public:
virtual int GetValue()=0;
};

Any smart pointer can function as a template based wrapper for a polymorphic
type.Cy


The interface is based on dynamic polymorphism, but the target type is
static polymorphism.
The target types (Penny, Dime, ....) are not derived from any class,
and Coins is just an interface to the static type.
This method mixes both dynamic polymorphism an static polymorphism to
get a heterogeneous container.

And, yes you could use a smart pointer to do this with an interface
class like Coins and the static holder class like TargetClassHolder.
std::vector<smart_ptr<Coins> > heterogeneousContainer;

heterogeneousContainer.push_back(TargetClassHolder <Nickel>);

That would work too.

Jun 1 '06 #14

This discussion thread is closed

Replies have been disabled for this discussion.