DISCLAIMER: Keep reading only if you want to see how it's NOT done. Apparently it's so wrong you will get eye cancer from it when you see it (I'm immune because I'm a noob :)
So I was thinking about runtime polymorphism in C++ for a while and I came up with the following. Consider this
#include <iostream>
struct Animal
{
virtual ~Animal(){}
void make_noise() const {return do_make_noise();}
protected:
Animal( ){}
virtual void do_make_noise()const{std::cout << "Meh\n";}
};
struct Cat:public Animal
{
void do_make_noise()const{ std::cout<< "meow\n";}
};
struct Dog:public Animal
{
void do_make_noise()const{ std::cout<< "woof\n";}
};
int main()
{
Cat cat;
Dog dog;
Animal a((const Animal&)cat); //every tutorial teaches us that this is bad!!
a.make_noise();
a = (const Animal&)dog;
a.make_noise();
return 0;
}
As you would expect the output is
Meh
Meh
OK, object slicing is bad :/
But now let me change the Base class slightly:
struct Animal
{
virtual ~Animal(){}
void make_noise() const {return ptr_->do_make_noise();}
protected:
Animal( ):ptr_(this){}
Animal* ptr_;
virtual void do_make_noise()const{std::cout << "Meh\n";}
};
Then the result is
meow
woof
Haha. Screw object slicing ...
What do you think of it? It seems to me that it has many advantages to be able to copy by value and still get the polymorphic behaviour. Is there a reason why people do not use this? Or am I just reinventing the wheel here?