polymorphism code not doing what I want

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
closed account (48T7M4Gy)
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
closed account (48T7M4Gy)
BTW n should be initialised (defaulted) to get rid of those junk values being displayed.
does anybody know why this is happening?


http://stackoverflow.com/questions/15188894/why-doesnt-polymorphism-work-without-pointers-references - particularly the second para of the accepted answer
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
closed account (48T7M4Gy)
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
closed account (48T7M4Gy)
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
thanks Kemort,that's the first time I've heard of slicing something new to learn :)
Topic archived. No new replies allowed.