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

Polymorphism - run-time vs. compile-time

P: n/a
Hello,
The other day I was rather shocked to find that I couldn't find
a good use for runtime polymorphism! Let me explain this a bit further
before you get shocked. Any function that I could previously write like
this:
void func1(Base& obj)
{
//...
obj.virmeth(); //Call virtual method
//...
}

Is now better written as this for most cases:
template <class T> void func1(T& obj)
{
//...
obj.virmeth(); //Call any method
//...
}

That way, I'll never incurr run-time overheads. Obviously, this
wouldn't
work if I'm trying to separate implementation from use, but this
question hit me so suddenly, that I really couldn't find a good answer
then. Now I figured out two situations where this isn't possible: when
return type must be polymorphic (or is that also used in automatic
template specialization?) ... or when catching exceptions. But I'd
still like to shake myself off this uneasy feeling by hearing a bit
more over which is more suitable when - and even in the cases I
mentioned, I'd like a little discussionW (exceptional cases etc.)

Samee

Jul 23 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Samee Zahur wrote:
Hello,
The other day I was rather shocked to find that I couldn't find
a good use for runtime polymorphism!
That would shock me too ;-)
Let me explain this a bit further before you get shocked. Any function
that I could previously write like this:
void func1(Base& obj)
{
//...
obj.virmeth(); //Call virtual method
//...
}

Is now better written as this for most cases:
template <class T> void func1(T& obj)
{
//...
obj.virmeth(); //Call any method
//...
}

That way, I'll never incurr run-time overheads. Obviously, this
wouldn't work if I'm trying to separate implementation from use, but this
question hit me so suddenly, that I really couldn't find a good answer
then. Now I figured out two situations where this isn't possible: when
return type must be polymorphic (or is that also used in automatic
template specialization?) ... or when catching exceptions. But I'd
still like to shake myself off this uneasy feeling by hearing a bit
more over which is more suitable when - and even in the cases I
mentioned, I'd like a little discussionW (exceptional cases etc.)


What if the actual type of the object is not determined at compile time, but
at runtime? Think of one classic example - a drawing program. The user can
draw circles, rectangles, text, whatever. When painting the objects on the
screen, the program goes through the list of objects and renders them all.
How does the program know at compile time, which paint function to call for
each of the objects?

Jul 23 '05 #2

P: n/a
Samee Zahur wrote:

Hello,
The other day I was rather shocked to find that I couldn't find
a good use for runtime polymorphism! Let me explain this a bit further
before you get shocked. Any function that I could previously write like
this:
void func1(Base& obj)
{
//...
obj.virmeth(); //Call virtual method
//...
}

Is now better written as this for most cases:
template <class T> void func1(T& obj)
{
//...
obj.virmeth(); //Call any method
//...
}


That's not better.
The important part in polymorphism is exactly that: You don't
know the runtime type T during compile time. Well, if you
don't know it, how should the compiler know when it instantiates
the template?

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #3

P: n/a
To everyone, thanks ...
Even these textbook examples did unclog my mind quite a bit.

Samee

Jul 23 '05 #4

P: n/a
Karl Heinz Buchegger wrote:
Samee Zahur wrote:
Is now better written as this for most cases:
template <class T> void func1(T& obj)
{
//...
obj.virmeth(); //Call any method
//...
}

That's not better.
The important part in polymorphism is exactly that: You don't
know the runtime type T during compile time. Well, if you
don't know it, how should the compiler know when it instantiates
the template?


You don't know it?
You mean - when you do:

int main () {
std::vector<std::string> test = "woop";
std::string * p2test = test;
func1(test);
return 0;
}

You DON'T know test?
Now, I personally think polymorphism is to generalize the function so
you don't have to write out several different versions of the same
function for different data types.

Please, explain..
And that code, I make no claims it is compilable - nor 100% correct....
I don't like pointers much.

--
Tr0n
--
Jul 23 '05 #5

P: n/a
Tr0n wrote:
That's not better.
The important part in polymorphism is exactly that: You don't
know the runtime type T during compile time. Well, if you
don't know it, how should the compiler know when it instantiates
the template?

You don't know it?
You mean - when you do:

int main () {
std::vector<std::string> test = "woop";
std::string * p2test = test;
func1(test);
return 0;
}

You DON'T know test?


The OP was talking about polymorphism.
The above has nothing to do with polymorphism, the above is
simply a pointer to an object.
Now, I personally think polymorphism is to generalize the function so
you don't have to write out several different versions of the same
function for different data types.


You obviously haven't understood what polymorphism is for and
what problem it solves.

Eg.

class Animal
{
public:
virtual void MakeNoise() {}
};

class Cat : public Animal
{
public:
virtual void MakeNoise() { std::cout << "Miau\n"; }
};

class Dog : public Animal
{
public:
virtual void MakeNoise() { std::cout << "Wuff\n"; }
};

void foo( Animal* pAnimal )
{
pAnimal->MakeNoise(); // here is the polymorphic call
// does pAnimal point to a Cat
// or a Dog? Nobody knows at this
// place. But it doesn't matter.
// Thanks to polymorphism the correct
// MakeNoise() function for Cats and/or Dogs
// is called.
}

int main()
{
Animal* Pets[2];

Pets[0] = new Cat;
Pets[1] = new Dog;

foo( Pets[0] );
foo( Pets[1] );

delete Pets[0];
delete Pets[1];
}

I invite you now to find a way to rewrite MakeNoise and foo
using templates without altering main() such that the program
behaves the very same.

Good luck!

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #6

P: n/a
Tr0n² wrote:
Karl Heinz Buchegger wrote:
Samee Zahur wrote:
Is now better written as this for most cases:
template <class T> void func1(T& obj)
{
//...
obj.virmeth(); //Call any method
//...
}
That's not better.
The important part in polymorphism is exactly that: You don't
know the runtime type T during compile time. Well, if you
don't know it, how should the compiler know when it instantiates
the template?


You don't know it?
You mean - when you do:

int main () {
std::vector<std::string> test = "woop";
std::string * p2test = test;
func1(test);
return 0;
}

You DON'T know test?


You do know it. But this is not an example for polymorphism.
Just let's try another example, where polymorphism is actually used:

#include <vector>
#include <string>
#include <iostream>

class Base
{
public:
virtual void do_something() = 0;
virtual ~Base() {}
};

class Derived1 : public Base
{
public:
virtual void do_something()
{
std::cout << "We're Derived1\n";
}

virtual ~Derived1()
{
std::cout << "Destroyed a Derived1\n";
}
};

class Derived2 : public Base
{
public:
virtual void do_something()
{
std::cout << "Now this is a Derived2\n";
}

virtual ~Derived2()
{
std::cout << "Oh no, I'm such a young Derived2, don't kill me\n";
}
};

int main()
{
std::vector<Base*> vec;
std::cout << "Instance of which type to add?";
std::string name;

for(;;)
{
std::cin >> name;

if (name == "end")
break;

if (name == "Derived1")
vec.push_back(new Derived1);
else
vec.push_back(new Derived2);
}

for (int i = 0; i < vec.size(); ++i)
vec[i]->do_something();

for (int i = 0; i < vec.size(); ++i)
delete vec[i];
}

Now, please rewrite that to use templates instead of virtual functions.
Now, I personally think polymorphism is to generalize the function so
you don't have to write out several different versions of the same
function for different data types.


No, it's not. That's what templates are for.

Jul 23 '05 #7

P: n/a
Rolf Magnus wrote:
Tr0n² wrote: <snip>
Now, please rewrite that to use templates instead of virtual functions.

Now, I personally think polymorphism is to generalize the function so
you don't have to write out several different versions of the same
function for different data types.

No, it's not. That's what templates are for.


Ahhh - thank you very much, Karl and Rolf.
I also say thank you for not taking it the wrong way, and simply
pointing at me and laughing instead of throwing the proverbial stick!

I half understand now... It's to do with objects with virtual functions
- the actions of which can change depending on the object.

And yes, I'm at the start of my journey down the yellow brick road - but
I'm sure not going to stop at the first crack.

Thanks for your assistance.

--
Tr0n
--
Jul 23 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.