Feb 27, 2017 at 3:41pm UTC
Hi guys I want to create an array of monster objects and have each individual monster attack for example a ghost object should use it's attack,I set a virtual function but everytime I run this code instead of the ghost or ninjas attack function getting called the monster attack function gets called,does anybody know why this is happening? and how I can fix this?
Thanks
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
#include <iostream>
using namespace std;
class monster{
protected :
int attack;
public :
virtual void Attack(){
cout << "monster attack" << endl;
}
void setAttackPower(int n){
attack = n;
}
};
class ninja: public monster{
public :
void Attack(){
cout << "ninja attack" << attack << endl;
}
};
class ghost: public monster{
public :
void Attack(){
cout << "ghost attack" << attack << endl;
}
};
int main()
{
ninja nin;
monster *one = &nin;
ghost go;
monster *two = &go;
monster monList[2];
monList[0] = nin;
monList[1] = go;
for (int i = 0; i < 2; i++){
monList[i].Attack();
}
}
I also tried doing this but got a compiler error and not sure why
1 2 3 4 5 6 7 8 9 10 11 12
ninja nin;
monster *one = &nin;
ghost go;
monster *two = &go;
monster *m = new monster[2];
m[0] = &nin;
Last edited on Feb 27, 2017 at 3:53pm UTC
Feb 27, 2017 at 4:01pm UTC
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
#include <iostream>
using namespace std;
class monster{
protected :
int attack;
public :
virtual void Attack(){
cout << "monster attack" << endl;
}
void setAttackPower(int n){
attack = n;
}
};
class ninja: public monster{
public :
void Attack(){
cout << "ninja attack" << attack << endl;
}
};
class ghost: public monster{
public :
void Attack(){
cout << "ghost attack" << attack << endl;
}
};
int main()
{
ninja nin;
ghost go;
monster* monList[2];
monList[0] = &nin;
monList[1] = &go;
for (int i = 0; i < 2; i++){
monList[i] -> Attack();
}
}
ninja attack0
ghost attack58560
Program ended with exit code: 0
Last edited on Feb 27, 2017 at 4:02pm UTC
Feb 27, 2017 at 4:06pm UTC
BTW n should be initialised (defaulted) to get rid of those junk values being displayed.
Feb 27, 2017 at 8:40pm UTC
thanks guys
just wondering how come the code which you posted works(displays each class's own attack function)
1 2 3 4 5 6 7 8 9 10 11 12 13
ninja nin;
ghost go;
monster* monList[2];
monList[0] = &nin;
monList[1] = &go;
for (int i = 0; i < 2; i++){
monList[i] -> Attack();
and this doesn't(just displays the default monster's attack function)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
ninja nin;
monster *one = &nin;
ghost go;
monster *two = &go;
monster monList[2];
monList[0] = nin;
monList[1] = go;
for (int i = 0; i < 2; i++){
monList[i].Attack();
}
Last edited on Feb 27, 2017 at 8:47pm UTC
Feb 27, 2017 at 10:29pm UTC
just wondering how come the code which you posted works(displays each class's own attack function)
The reason is as the article from gunnerfunner explains. The overall problem is called 'slicing' where saving the various inherited objects as objects slices the information so that they 'become' base class objects on retrieval. To overcome this the objects must be saved as pointers. In this case they are saved as an array of pointers to monsters, not an array of monsters.
So when they are recalled from the array the elements are pointers so '->' instead of '.' applies.
Your main() should be:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
int main()
{
ninja nin;
monster *one = &nin;
ghost go;
monster *two = &go;
monster *monList[2];
monList[0] = one;
monList[1] = two;
for (int i = 0; i < 2; i++){
monList[i]->Attack();
}
}
Last edited on Feb 27, 2017 at 11:15pm UTC
Feb 28, 2017 at 3:39am UTC
Or more to the point:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
int main()
{
ninja nin;
ninja *one = &nin;
ghost go;
ghost *two = &go;
monster* monList[2];
monList[0] = one;
monList[1] = two;
for (int i = 0; i < 2; i++){
monList[i] -> Attack();
}
return 0;
}
ninja attack0
ghost attack58656
Program ended with exit code: 0
Last edited on Feb 28, 2017 at 3:40am UTC
Feb 28, 2017 at 1:42pm UTC
thanks Kemort,that's the first time I've heard of slicing something new to learn :)