Here is an example of the a double dispatch. Let's say it's a game. You have a wildanimal that attacks types of humans, and a warrior which derives from human. Let us consider a wildanimal attacking a warrior. I strongly suggest running this code for a better understanding.
The problem is on line 60 you have w->attack(h). This leads to static compile time function overloading and you end up selecting the 'Human Attack' at line 44. This leads to a wild animal attacking a human despite the fact that it should be attacking a warrior.
The solution is to have a DD that allows the proper dynamic cast by using the 'this' pointer (line 26). Now when you call h->attackedbywildanimal(w); at line 54 you will get the correct wild animal attacking a warrior instead of a human.
Note that a simpler but far less flexible solution would have been to simply statically cast the pointer at line 50 to be w->attack((warrior*)h);.
Note that to have all the code in a single file I needed class definitions at the top and the wildanimal implementation is actuall at the bottom. Remind me to use java next time!
1. #include <iostream> 2. 3. using namespace std; 4. 5. class human; 6. class warrior; 7. class wildanimal{ 8. public: 9. virtual void attack(human*); 10. virtual void attack(warrior*); 11. }; 12. 13. class human{ 14. public: 15. virtual void attackedbywildanimal(wildanimal *animal){ 16. animal->attack(this); 17. } 18. void GetHealth(){ 19. cout<<"Human health\n"; 20. } 21. }; 22. 23. class warrior : public human{ 24. public: 25. virtual void attackedbywildanimal(wildanimal *animal){ 26. animal->attack(this); 27. } 28. void GetHealth(){ 29. cout<<"Warrior health\n"; 30. } 31. }; 32. 33. void wildanimal::attack(human* h){ 34. cout<<"Animal attacks human "; 35. h->GetHealth(); 36. } 37. void wildanimal::attack(warrior* w){ 38. cout<<"Animal attacks warrior "; 39. w->GetHealth(); 40. } 41. 42. class boar: public wildanimal{ 43. public: 44. void attack(human* h){ 45. cout<<"Boar attacks human "; 46. h->GetHealth(); 47. } 48. void attack(warrior* w){ 49. cout<<"Boar attacks warrior "; 50. w->GetHealth(); 51. } 52. }; 53. 54. int main(int argv, char** argc){ 55. 56. human * h = new warrior(); 57. wildanimal * w = new boar(); 58. 59. //Problem 60. w->attack(h); 61. 62. //Double Dispatch solution 63. h->attackedbywildanimal(w); 64. } |
0 comments:
Post a Comment