Some thoughts on polymorphism

C

chsalvia

I've been programming in C++ for a little over 2 years, and I still
find myself wondering when I should use polymorphism.

Some people claim that polymorphism is such an integral part of C++,
that anybody who doesn't use it might as well just program in plain
C. I totally disagree with this, because I think C++ has a lot of
great features apart from polymorphism, such as the ability to
organize code into classes, code reuse through inheritance, templates,
template specialization, etc.

Still, most people promote C++ and OO in general because of
polymorphism. But for some reason, I find the idea of defining lots
of little classes that inherit from a base class to be a bit
overreaching just to do something that essentially boils down to a
function pointer.

Take the following example:

Recently I was working on a project where a server would interpret
various commands issued by a client. There were about 25 different
possible commands. Each command the client issues should cause the
server to respond in a different way.

So what's the best way to implement this in C++?

The first thing that came to mind was a typical C approach: make a
hash table of key words (commands), and associate each key with a
function pointer. This is simple and extremely efficient. But since
I'm programming in C++ I feel compelled to explore more OOish
alternatives. Also, the server program itself was a class, so I'd
need to have the hash table store pointers to functions which are not
part of the class, which kind of breaks the whole design. (Unless I
use dreaded member function pointers - which __nobody__ ever uses, and
which entail considerable overhead to dereference.)

So, I thought: how about polymorphism? I could create an abstract
base class "command", with a single virtual function, and then make 25
little classes which inherit from it. Then I could just have a
generic execute() function, like:

void execute_command(Command* c)
{
c->dosomething();
}

This seems like it would be the standard C++ way of doing this.
Still, there's something about it that just seems ridiculous. I
define 25 classes, just so I can pick between functions dynamically.
On top of that, doing this the old fashioned way (a table of plain
function pointers) is more efficient, since it doesn't involve the
vtable.

For some reason, I don't feel like C++ offers an elegant solution to
this problem. Am I just being too picky? Or does anyone agree?
Comments, thoughts, suggestions, would be appreciated.
 
J

Jim Langston

I've been programming in C++ for a little over 2 years, and I still
find myself wondering when I should use polymorphism.

Some people claim that polymorphism is such an integral part of C++,
that anybody who doesn't use it might as well just program in plain
C. I totally disagree with this, because I think C++ has a lot of
great features apart from polymorphism, such as the ability to
organize code into classes, code reuse through inheritance, templates,
template specialization, etc.

Still, most people promote C++ and OO in general because of
polymorphism. But for some reason, I find the idea of defining lots
of little classes that inherit from a base class to be a bit
overreaching just to do something that essentially boils down to a
function pointer.

Take the following example:

Recently I was working on a project where a server would interpret
various commands issued by a client. There were about 25 different
possible commands. Each command the client issues should cause the
server to respond in a different way.

So what's the best way to implement this in C++?

The first thing that came to mind was a typical C approach: make a
hash table of key words (commands), and associate each key with a
function pointer. This is simple and extremely efficient. But since
I'm programming in C++ I feel compelled to explore more OOish
alternatives. Also, the server program itself was a class, so I'd
need to have the hash table store pointers to functions which are not
part of the class, which kind of breaks the whole design. (Unless I
use dreaded member function pointers - which __nobody__ ever uses, and
which entail considerable overhead to dereference.)

So, I thought: how about polymorphism? I could create an abstract
base class "command", with a single virtual function, and then make 25
little classes which inherit from it. Then I could just have a
generic execute() function, like:

void execute_command(Command* c)
{
c->dosomething();
}

This seems like it would be the standard C++ way of doing this.
Still, there's something about it that just seems ridiculous. I
define 25 classes, just so I can pick between functions dynamically.
On top of that, doing this the old fashioned way (a table of plain
function pointers) is more efficient, since it doesn't involve the
vtable.

For some reason, I don't feel like C++ offers an elegant solution to
this problem. Am I just being too picky? Or does anyone agree?
Comments, thoughts, suggestions, would be appreciated.

What you describe doesn't sound like a good use for polymorphism
necessarily. There are a lot of places to use polymorphism, and a lot of
places not to use it.

Take, for instance, a game I'm writing. The clients sent commands to the
server. I interpret the commands in pretty much a C way. However, these
commands work on objects using OOPs, as a character is an object which can
be either a player or an NPC (non player character). Which is where the
polymorphism comes in.

The time I usually find I want to use polymorphism is when I want a
container of objects that can be of different types, players or NPCs.
 
P

pmouse

Over the years I've found people arguable on this issue many, many
times. People talk about procedural programming, OO, Generic
Programming, etc. Different people holds different beliefs and are
used to their own style of programming. You can argue about these for
years and not have a result.

My view is, for simple problems, C style "procedural model" suits me
the best. The problem you mentioned belongs to the simple case. For
large and complex systems, the OO model offers a systematic DESIGN
approach, the keyword here is "DESIGN", not implementation efficiency.

Regards,

PQ
 
D

Dennis Jones

Take the following example:

Recently I was working on a project where a server would interpret
various commands issued by a client. There were about 25 different
possible commands. Each command the client issues should cause the
server to respond in a different way.

So what's the best way to implement this in C++?

So, I thought: how about polymorphism? I could create an abstract
base class "command", with a single virtual function, and then make 25
little classes which inherit from it. Then I could just have a
generic execute() function, like:

void execute_command(Command* c)
{
c->dosomething();
}

This seems like it would be the standard C++ way of doing this.
Still, there's something about it that just seems ridiculous. I
define 25 classes, just so I can pick between functions dynamically.
On top of that, doing this the old fashioned way (a table of plain
function pointers) is more efficient, since it doesn't involve the
vtable.

For some reason, I don't feel like C++ offers an elegant solution to
this problem. Am I just being too picky? Or does anyone agree?
Comments, thoughts, suggestions, would be appreciated.

Well, for something this simple, it might not seem to make a lot of sense to
use classes, but there may still be some advantages to doing so.

Consider future changes. Adding a new command to a complex conditional
statement requires a certain amount of effort, even if just a little. If
that conditional statement (or similar conditionals) exists in more than one
place in your program, you will find yourself duplicating that same effort
wherever those conditional statements exist.

If you use polymorphism instead, a complex conditional statement (e.g. a
switch) may be replaced by polymorphism, which not only makes the code
easier to read, but also adding a new command later could be as simple as
creating a class to encapsulate the desired behavior. Granted, creating a
class with the appropriate method is a little more work than writing a
function, but not by much. The amount of readability and ease of
maintenance you gain by doing so will probably outweigh the effort you
expend.

That's just one advantage I can think of off the top of my head. Perhaps
someone else will offer others.

- Dennis
 
?

=?iso-8859-1?q?Kirit_S=E6lensminde?=

I've been programming in C++ for a little over 2 years, and I still
find myself wondering when I should use polymorphism.

Some people claim that polymorphism is such an integral part of C++,
that anybody who doesn't use it might as well just program in plain
C. I totally disagree with this, because I think C++ has a lot of
great features apart from polymorphism, such as the ability to
organize code into classes, code reuse through inheritance, templates,
template specialization, etc.

Still, most people promote C++ and OO in general because of
polymorphism. But for some reason, I find the idea of defining lots
of little classes that inherit from a base class to be a bit
overreaching just to do something that essentially boils down to a
function pointer.

Take the following example:

Recently I was working on a project where a server would interpret
various commands issued by a client. There were about 25 different
possible commands. Each command the client issues should cause the
server to respond in a different way.

So what's the best way to implement this in C++?

The first thing that came to mind was a typical C approach: make a
hash table of key words (commands), and associate each key with a
function pointer. This is simple and extremely efficient. But since
I'm programming in C++ I feel compelled to explore more OOish
alternatives. Also, the server program itself was a class, so I'd
need to have the hash table store pointers to functions which are not
part of the class, which kind of breaks the whole design. (Unless I
use dreaded member function pointers - which __nobody__ ever uses, and
which entail considerable overhead to dereference.)

So, I thought: how about polymorphism? I could create an abstract
base class "command", with a single virtual function, and then make 25
little classes which inherit from it. Then I could just have a
generic execute() function, like:

void execute_command(Command* c)
{
c->dosomething();

}

This seems like it would be the standard C++ way of doing this.
Still, there's something about it that just seems ridiculous. I
define 25 classes, just so I can pick between functions dynamically.
On top of that, doing this the old fashioned way (a table of plain
function pointers) is more efficient, since it doesn't involve the
vtable.

For some reason, I don't feel like C++ offers an elegant solution to
this problem. Am I just being too picky? Or does anyone agree?
Comments, thoughts, suggestions, would be appreciated.

I write stuff with a similar requirement a lot. There are all sorts of
dynamic plug-in routines that need to be run at various times
depending on a whole host of factors. As you suggest the standard way
that I implement this is as some sort of function lookup. Does that
mean C++ is pointless? I think that's looking at it in the wrong way.

One thing that I keep repeating in different ways is that we should be
dogmatic about our results, not our methods. We need to use the right
solution for a given problem, not the one that we feel we are
"supposed" to use. The truth is that C++ opens more ways of solving a
problem than any other language I've used. If a table of function
pointers is the right way to solve this problem then C++ lets you do
it.

C++ also lets you abstract out the table and the lookups into a
templated class so that it can be re-used. I've done this in FOST.3
because we use it so often for handling plug-ins and configurable
items. Now I can set up a new plug-in location with just a couple of
lines of code and the registration of the plug-ins is even thread-safe
so it doesn't matter when in the application's lifetime they are
loaded.

But what do you put in the table? You could store raw function
pointers, but it is probably a lot more flexible if you store a
boost::function0< void > because you can then store raw function
pointers, but you can also bind parameters (currying) to the functions
so that you can use the same function and configure the differences
more easily.

Sure, this feels more like functional programming (because that's
exactly what it is) than OO programming, but again, we use our tool to
give us the appropriate solution.

And you also get the benefit of classes when they are the right
abstraction. The only other languages I've come across that are this
flexible are the LISP family, but for some reason they're much less
popular (probably because they don't play as nicely with other
languages as C++ does).

In C++ you have an extraordinarily powerful tool that will allow you
to write the correct solution in the best way. Don't listen to anybody
who tells you that C++ is all about objects and certainly don't listen
to anybody who tells you that OO is about sub-classing (but that's a
story for another time).

The function table is just as OO as the classes in C++ are. It's just
that you're writing your own message dispatcher rather than using one
of the built in ones. That's cool.


K
 
D

Diwa

Recently I was working on a project where a server would interpret
various commands issued by a client. There were about 25 different
possible commands. Each command the client issues should cause the
server to respond in a different way.

So what's the best way to implement this in C++?

Would it make sense to use the "Command Pattern" from Design Patterns
here ?

-- Diwakar
 
J

James Kanze

I've been programming in C++ for a little over 2 years, and I still
find myself wondering when I should use polymorphism.
Some people claim that polymorphism is such an integral part of C++,
that anybody who doesn't use it might as well just program in plain
C. I totally disagree with this, because I think C++ has a lot of
great features apart from polymorphism, such as the ability to
organize code into classes, code reuse through inheritance, templates,
template specialization, etc.

Polymorphism is only one paradigm. Use it when it's
appropriate; use something else when something else is
appropriate. I find it hard to imagine any largish application
in C++ that didn't make some use of polymorphism, but I am very
sceptical of making everything polymorphic.
Still, most people promote C++ and OO in general because of
polymorphism. But for some reason, I find the idea of defining lots
of little classes that inherit from a base class to be a bit
overreaching just to do something that essentially boils down to a
function pointer.

A function pointer, plus a lot of other things.
Take the following example:
Recently I was working on a project where a server would interpret
various commands issued by a client. There were about 25 different
possible commands. Each command the client issues should cause the
server to respond in a different way.
So what's the best way to implement this in C++?
The first thing that came to mind was a typical C approach: make a
hash table of key words (commands), and associate each key with a
function pointer. This is simple and extremely efficient. But since
I'm programming in C++ I feel compelled to explore more OOish
alternatives. Also, the server program itself was a class, so I'd
need to have the hash table store pointers to functions which are not
part of the class, which kind of breaks the whole design. (Unless I
use dreaded member function pointers - which __nobody__ ever uses, and
which entail considerable overhead to dereference.)

I've used member function pointers on several occasions. It's
one possible solution. If the commands need access to the
context of the calling class, it can be justified.
So, I thought: how about polymorphism? I could create an abstract
base class "command", with a single virtual function, and then make 25
little classes which inherit from it. Then I could just have a
generic execute() function, like:
void execute_command(Command* c)
{
c->dosomething();
}
This seems like it would be the standard C++ way of doing this.
Still, there's something about it that just seems ridiculous. I
define 25 classes, just so I can pick between functions dynamically.

Also, of course, initialize the hash table automatically, and
provide each command with its own environment. Both things that
are bothersome with just function pointers.
On top of that, doing this the old fashioned way (a table of plain
function pointers) is more efficient, since it doesn't involve the
vtable.

Who cares? The difference won't be measurable. (And in
practice, is just as likely to favor derivation.)
For some reason, I don't feel like C++ offers an elegant solution to
this problem.

If you find a table of function pointers, which you have to
manually initialize, and an absense of any context for the
called function elegant...
 
B

Branimir Maksimovic

On May 2, 5:43 am, (e-mail address removed) wrote:
Also, the server program itself was a class, so I'd
need to have the hash table store pointers to functions which are not
part of the class, which kind of breaks the whole design. (Unless I
use dreaded member function pointers - which __nobody__ ever uses, and
which entail considerable overhead to dereference.)
Actually overhead for calling member functions through pointers
is not that big.
In one implementation I saw, for example, there is no overhead for
calling non virtual member functions, but for virtual calls,compiler
creates small stub code consisting of two instructions (one
instruction
loads function address from vtable, other instruction is indirect
jump)
and sets the address of that code in member pointer,
which is actually just plain function pointer.
Other implementation I saw use fat member pointer
which contains info whether pointer contains plain pointer
to function or offset into vtable.
In that implementation overhead is check for that value
and conditional jump to appropriate call.

Greetings, Branimir.
 
F

faceman28208

I've been programming in C++ for a little over 2 years, and I still
find myself wondering when I should use polymorphism.

The reality is polymorphism really doesn't show great value unless you
have a sufficent number number of related classes. Thus most academic
examples are pretty worthless.

Places where polymophism shows great value:
- Libraries for manging object in w windowing systems (e.g. M$ or X).
Each object is a window that has common properties and methods, such
as location and show/hide.
- Code that manipulates trees and graphs where nodes can be of
different type. Examples might include a compiler parse tree.

The clue that you have a situation where you should be using
polymorphism is usually a large number of switch statements that do
casts.

This may sound like apostacy but in my experience most software
projects have little need for new (as in outside existing libraries)
polymorphism because they simply do not have the types of class
relationships that can take advantage of it. Most programming problems
need only functions and concrete types.
 
?

=?iso-8859-1?q?Kirit_S=E6lensminde?=

The reality is polymorphism really doesn't show great value unless you
have a sufficent number number of related classes. Thus most academic
examples are pretty worthless.

In some ways it is only a minor point, but polymorphism isn't
inheritance, although inheritance is a form of polymorphism. There are
many other polymorphic constructs in C++.

std::list (and the rest of the STL containers) are polymorphic
classes. std::max is a polymorphic function as are the ones in
<algorithm>. Even the C operator + (which C++ inherits) is
polymorphic.

There are lots and lots of forms of polymorphism and many of them can
be used in C++ (but not all of them). Some of the ones that C++
doesn't support are still very useful to understand. For example row
polymorphism can be used to analyse the type constraints that
templates impose.


K
 
P

pmouse

In some ways it is only a minor point, but polymorphism isn't
inheritance, although inheritance is a form of polymorphism. There are
many other polymorphic constructs in C++.

std::list (and the rest of the STL containers) are polymorphic
classes. std::max is a polymorphic function as are the ones in
<algorithm>. Even the C operator + (which C++ inherits) is
polymorphic.

Well, not really, the stl containers uses generic programming
concepts, they work on the basis of "policies" rather than
inheritance, and they can't really be called "polymorphic".

Regards,

PQ
 
?

=?iso-8859-1?q?Kirit_S=E6lensminde?=

Well, not really, the stl containers uses generic programming
concepts, they work on the basis of "policies" rather than
inheritance, and they can't really be called "polymorphic".

That's a very odd definition of polymorphism that you're using - it's
also wrong.

What you're talking about is "inclusional polymorphism". C++ has this
form in common with languages like Java which are more strongly typed.
Most other OO languages (the so called dynamic languages) primarily
use another form of polymorphism called "operational polymorphism" or
more commonly "duck typing". C++ has a limited form of this that can
be used at compile time.

It is also possible to convert from operational to inclusional
polymorphism[1] and the requirements that a template puts on the types
it can be used with can be analysed through something called row
polymorphism.

[1] http://www.kirit.com/Walking, talking and quacking in Java

You are making a mistake common amongst C++ and Java programmers of
confusing inclusional polymorphism and polymorphism in general which
is exactly why I raised the point.

Note that pure functional languages are polymorphic but don't have any
class inheritance (not in the sense we mean in C++ anyway). Google for
"Haskell" or "ML" and "polymorphism" and you will notice the
discussion is about exactly the same forms that the STL uses.


K
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,967
Messages
2,570,148
Members
46,694
Latest member
LetaCadwal

Latest Threads

Top