Issue with inheritance

I made this little code to try understanding more the concept of inheritance
and I came to a problem.

At the line where I told Luis to attack Gerry (In Main.cpp), the compiler dropped an error that says : no matching function to call to 'Wizard::attack(Character&)'

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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//MAIN.CPP

#include <iostream>
#include "Character.h"
#include "Wizard.h"

using namespace std;

int main()
{
    Wizard Luis;
    Character Gerry ;
     cout<<"Gerry Attack Luis"<<endl;
    Gerry.attack(Luis);
     cout<<"Gerry ";
    Gerry.showlife();
     cout<<"Luis ";
    Luis.showlife();
     cout<<"Gerry "<<endl;
    Luis.attack(Gerry);                    //this line here
     cout<<"Gerry ";
    Gerry.showlife();
     cout<<"Gerry ";
    Luis.showlife();
     cout<<"Gerry drink a potion, now he got : ";
    Gerry.heal(20);
    return 0;
}

//WIZARD.CPP

#include "Wizard.h"

using namespace std;

Wizard::Wizard() :Character(),m_mana (75),m_Fire_dmg(17)
{

}


void Wizard::fireball (int m_Fire_dmg, int m_dmg)
{
  m_vie -= (m_Fire_dmg += m_dmg);
  cout<<" is throwing a Fire Ball at ";
}

void Wizard::attack (Wizard &target)

{
    target.fireball(m_Fire_dmg,m_dmg);
}


//CHARACTER.CPP

#include "Character.h"
#include "Wizard.h"
#include <iostream>

using namespace std;

Character::Character():m_vie(100),m_dmg(23),m_potion(20)
{

}


void Character::getdmg (int m_dmg)
{
 m_vie -= m_dmg;
}

void Character::attack (Character &target)
{
 target.getdmg(m_dmg);
}


void Character:: heal (int m_potion)
{
 m_vie += m_potion;

  if (m_vie>100)
   {
    m_vie = 100 ;
   }
  cout<<m_vie<<" HP"<<endl;
}

 void Character::showlife ()const
{
 cout<<" a "<<m_vie<<" HP"<<endl;
}



Is it possible that the compiler's throwing that error because it need to sort of convert one of the object to make them able to interact together?
Like Character is not a Wizard type?
Last edited on
You forgot to post Wizard.h and Character.h.
You made a little mistake.

void Wizard::attack (Wizard &target)

This means your wizard object can only attack other wizard objects.
You have to do this.

void Wizard::attack (Character &target)

This way your wizard object can attack all character objects aswell as wizard objects.
You also have to change the attack function of wizard since you are calling a function that only wizard has.

target.fireball(m_Fire_dmg,m_dmg); //this
Can you explain to me what is actually wrong with ;target.fireball(m_Fire_dmg,m_dmg); I'm not sure I quite understand what you are thinking actually, It seems to me that if I correct the declaration of the method like you told me :void fireball (Character & target), only wizard will be able to cast a fireball am I wrong?, I just need more precise explanation, english ain't my primary labguage so.. Thx for your comphrension


BTW : I'll import both Wizard.h and Character.h afterwork to this thread
Last edited on
Can you explain to me what is actually wrong with ;target.fireball(m_Fire_dmg,m_dmg);

Your fireball function is a member of your Wizard class. Since you invoke it as target.fireball(), target must be a Wizard. Character has no such function, so your target can't be a Character.

If you want a Wizard to throw a fireball at another character (which might be another Wizard), I would make the signature look like this:
1
2
3
4
5
6
void Wizard::throw_fireball (Character & target)
{  //  Now we can manipulate the attributes of the target Character
}
...
  Luis.throw_fireball (Gerry);
  //  Note that Gerry can't throw a fireball at Luis because Gerry is not a Wizard. 


If you want any Character to be able to throw a fireball (which I doubt), then make throw_fireball() a member of the Character class.
Last edited on
I have fixed my method with your advise and the compiler compiled it, I have remove the void Wizard::attack() method and merge it into the void Wizard::fireball() method

/
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

//Wizard.cpp


#include "Wizard.h"

using namespace std;

Wizard::Wizard() :Character(),m_mana (75),m_Fire_dmg(17)
{

}


void Wizard::fireball (Character &target)
{
  m_vie -= (m_Fire_dmg += m_dmg);
  cout<<" is throwing Fireballs at ";
}


//Main.cpp

#include <iostream>
#include "Character.h"
#include "Wizard.h"

using namespace std;

int main()
{
    Wizard Luis;
    Character Gerry ;
     cout<<"Gerry Attack Luis"<<endl;
    Gerry.attack(Luis);
     cout<<"Gerry ";
    Gerry.showlife();
     cout<<"Luis ";
    Luis.showlife();
     cout<<"Luis ";
    Luis.fireball(Gerry);
     cout<<"Gerry "<<endl;
      cout<<"Gerry "<<endl;
    Gerry.showlife();
     cout<<"Luis "<<endl;
    Luis.showlife();
     cout<<"Gerry drink a potion, now he got : ";
    Gerry.heal(20);
    return 0;
}

When you execute it, the problem seems to be Luis throwing a Fireball at 127.0.0.1 ahaha
seriously it won't throw a fireball at Character
 
Look at lines 15-19. What variables are you accessing? Hint: You're accessing the Wizard's damage values. Don't you want to be updating the target's damage variables?

Still haven't seen the header for character.h or wizard.h you said you would post.



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

//Character.h


#ifndef CHARACTER_H
#define CHARACTER_H
#include <iostream>


class Character

{
  public:

   Character ();

    void getdmg (int m_dmg);
    void attack (Character &target);
    void heal (int m_potion);
    void showlife ()const;
    void s_attack(Character &target);




  protected:

    int m_vie = 100;
    int m_potion = 20;
    int m_dmg = 23;

};

#endif // CHARACTER_H


//Wizard.h


#ifndef WIZARD_H
#define WIZARD_H
#include "Character.h"


class Wizard : public Character
{
    public:
        Wizard();
        void fireball (Character &target);



    protected:

    private:

    int m_mana = 75;
    int m_Fire_dmg= 17;


};

#endif // WIZARD_H 


So i must put like
1
2
3
4
5
6
7
8

void Wizard::fireball (Character &target)
{
 
target.    m_vie -= (m_Fire_dmg += m_dmg)  // Wrap all those attributs  into a function that update target's damage variable
 
  cout<<" is throwing Fireballs at ";
}


Am I Wrong?
Last edited on
Am I Wrong?

That depends on what you're trying to do.

Line 5: You're adding the Wizard's dmg variable to the the Wizard's fire_dmg variable. Not sure why you're doing this. Did you intend to make the Wizard's fireball strength greater for each fireball thrown? One might assume that the Wizard has only a certain amount of fireball strength and is weakened, not strengthened for each fireball thrown.
 
target.m_vie -= (m_Fire_dmg += m_dmg) 

Then you're taking the (updated) Wizard's fire_dmg and subtracting that that from the targets m_vie. This part makes sense.

The m_dmg (normal attack damage) variable stand for the damage that Character can afflict tought, The m_Fire_dmg (fire attack damage) stand for the damage That Wizard afflict. My point is , We know that Wizard is a Character so I just want Wizard to sum the m_dmg and the m_Fire_dmg so it will represent the total damage that fireball is making. m_dmg+=m_Fire_dmg and after that I want to substract the sum of the 2 variable that represent the general damage of their object to m_vie who represent the health of Character and the Health of Wizard too, but in my case I still want to Attack Gerry the Character with the Luis's fireball
Last edited on
I Finally made it , thanks for your patience, I guess I'll need to read more about the whole concept of Class , Inheritance and pointer, there's always some details missing for some of my question with the information I end up with...

This is what I made

1
2
3
4
5
6
7
8
9
 

void Wizard::fireball (Character &target)
{
  m_Total_dmg = m_dmg+m_Fire_dmg;
  target.getdmg(m_Total_dmg);
  cout<<" is throwing a Fireball at  ";
}


getdmg() who belong to Character is finishing the request of Wizard for attacking a Character

1
2
3
4
5

void Character::getdmg (int m_dmg)
{
 m_vie -= m_dmg;
}


If you have a better Idea of how I should make this work I'm totally open for new idea or challenges for educational prupose, thx again!!
If you have a better Idea of how I should make this work

You've got the right idea.

A few of comments though:
1) line 5: Why is m_total_dmg a member variable? It can just be a local variable. Do you really need to save this value? I don't see that it adds any value to a Wizard.

2) target.getdmg(). This is a good idea to add to Character to allow adjusting its health. i.e. taking a hit. However, I would suggest naming this take_damage or something similar. get_xxx usually implies a getter which returns a value, rather than a modifier that adjusts a value.

3) I had earlier suggested renaming fireball to throw_fireball, making clear the action that is being taken and by whom.

4) getdmg() I would not suggest naming the argument with a m_ prefix. The m_ prefix is usually used to indicate a member variable. An argument is not a member variable.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void Wizard::fireball_cast (Character &target)
{
  m_Total_dmg = m_dmg+m_Fire_dmg;
  target.attack(m_Total_dmg);
  cout<<" is throwing a Fireball at  ";
}

........

void Character::attack (int total_dmg)
{
 m_vie -= total_dmg;
}

void Character::norm_attack (Character &target)
{
 target.attack(m_dmg);
}



1) 2) 3) and 4) haha ;)

Thanks AbstractionAnon for the hand that you've been giving to me , Hope of seeing you in another thread

Peace
Topic archived. No new replies allowed.