But why this?
Foo *foo = new Ham;
this is same as saying,
int *Foo = new char; |
Nah, not quite.
They are both datatypes and you can convert an int to a char but an int is not a char and a char is not an int, that's the difference between that and polymorphiosm.
However, you could use a void* to point to either int or char
Note that you need to convert the void* to a char* or int* to access the data
1 2 3 4 5 6 7 8 9 10 11
|
int main(void)
{
int a = 500;
char b = 65;
void* c = &b;
std::cout << *(char*)c << std::endl;
c = &a;
std::cout << *(int*)c << std::endl;
return 0;
}
|
I'll come back to that later
If you still wonder about that I'll give you the basics of polymorphism.
Imagine you have a TransportationObject. Yes, it's a transportation object, I couldn't think of a better name.
You might think about a Car or a Bike by now...
And yeah, both of them are TransportationObjects! :D
So without Polymorphism you might do something like this:
Imagine you have 2 different Obejcts which serve the same purpose (here you travel with them)
You choose 1 of them, but you'd do the same for every object.
switch/case looks good right?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
class TransportationObject
{
public:
virtual void travel() const
{
std::cout << "transportation:" << std::endl;
}
};
class Car : public TransportationObject
{
public:
virtual void travel() const { std::cout << "transportation: Car" << std::endl; }
};
class Bike: public TransportationObject
{
public:
virtual void travel() const { std::cout << "transportation: Bike" << std::endl; }
};
int main(void)
{
srand (time(NULL)); // for finding best choise
Car car;
Bike bike;
switch(rand() % 2)
{
// same algorithm twice
case 0: for(int i = 0; i < 100; ++i) car.travel(); break;
case 1: for(int i = 0; i < 100; ++i) bike.travel(); break;
default: break;
}
}
|
Yeah... it works
But you have the same algorithm for both cases so isn't there a better way?
Yes. the answer is, simple, use polymorphism, "when a class derives public from an other class the Derived class has a is-an-relation with the base class" (no quote)
That means a Car is a Transportation Object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
class TransportationObject
{
public:
virtual void travel() const
{
std::cout << "transportation:" << std::endl;
}
};
class Car : public TransportationObject
{
public:
virtual void travel() const { std::cout << "transportation: Car" << std::endl; }
};
class Bike: public TransportationObject
{
public:
virtual void travel() const { std::cout << "transportation: Bike" << std::endl; }
};
|
Now you have a Car and a Bike at home.
You don't know what you want to take so you... yeah... try to find out.
After finding out, you want to travel, maybe 100 times to different places?
Keep in mind, that Car and Bike are both TransportationObjects (public inheritance)
So logically speaking, you choose between 2 similar Objects.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
TransportationObject* find_best_choise(TransportationObject* o1,TransportationObject* o2)
{
switch(rand() % 2)
{
case 0: return o1;
case 1: return o2;
default: return nullptr;
}
}
int main(void)
{
srand (time(NULL)); // for finding best choise
Car car;
Bike bike;
TransportationObject* object = find_best_choise(&car, &bike);
// Now do something with the desired Object
for(int i = 0; i < 100; ++i)
object->travel();
}
|
You see, here you get the Object you want to work with and after that you don't care about that anymore.
To get back to the void* example, imagine Car has a Method called refill, and when traveling you want to refill your Car, but you don't need to refill your bike
in that case you have to cast it to the derived class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
|
enum { ID_GENERAL, ID_CAR, ID_BIKE };
class TransportationObject
{
public:
TransportationObject() : id(ID_GENERAL) {}
int id;
virtual void travel() const
{
std::cout << "transportation:" << std::endl;
}
};
class Car : public TransportationObject
{
public:
Car() : id(ID_CAR) {}
virtual void travel() const { std::cout << "transportation: Car" << std::endl; }
void refill() const { std::cout << "Car: refill" << std::endl; }
};
class Bike: public TransportationObject
{
public:
Bike() : id(ID_BIKE) {}
virtual void travel() const { std::cout << "transportation: Bike" << std::endl; }
};
int main(void)
{
srand (time(NULL)); // for finding best choise
Car car;
Bike bike;
TransportationObject* object = find_best_choise(&car, &bike);
// Now do something with the desired Object
for(int i = 0; i < 100; ++i)
{
// things you do with all objects
object->travel();
// things you do with spezific types
if(object->id == ID_CAR)
((Car*)(object))->refill();
}
}
|
I hope this post is easy to understand.