Calling the right function of a child class

I need to call the correct function from an object of a sub-class. Both the super-class and the sub-class have this function but the sub's is different. I am unable to make function virtual because I do need to be able to sometimes create an object of that type. The super-class also has inherits from its own super-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
class Character
{
     private:
          //A bunch of private member variables
     public:
          //Some other functions + constructor
          virtual void save() const = 0 {/*Definition of save()*/}
          virtual void attack(weapon blade, bool advan = false, bool disadvan = true) const = 0 {/*Definition of attack*/}
};

class Fighter : public Character
{
     private:
          //A few added member variables
     public:
          //A few added functions
          void save()
          {
               //Added save statements for a fighter
               Character::save();
          }
          void attack(weapon blade, bool advan = false, bool disadvan = false) {/*A little added flair and then calls Character::attack() with certain paramters.*/)
};

class BattleMaster : public Fighter
{
     private:
          //A few more member variables
     public:
          void save() {A bit more added statements
               Fighter::save();}
          void attack(weapon blade, bool advan = false, bool disadvan = false)
          {
                //A few more added statements
               Character::attack(); //With special parameters
          }
};

int main()
{
     Character* player = createCharacter(); //Creates a character based on user input.
     return 0;
}


So I have no idea of knowing what class the object will be until runtime. Is there anyway I can have a type of BattleMaster call the correct function if I later call something like player.save();? Or am I just going at this completely incorrectly?

--Thanks in advance for help!
Last edited on
I am unable to make function virtual because I do need to be able to sometimes create an object of that type.


You are mixing up "pure virtual" and "virtual".

You can make a function virtual in a class and still create objects of that class.
Last edited on
@Too Explosive , if you're going to insert comments, use "//" or "/* ... */" instead of { Hi, look at this distracting message! }
virtual void save() const = 0 {Definition of save()}


Lot of stuff is missing semicolons. Try to give a compiling example at least.
Right my bad. But even if I declare the function in Fighter as virtual it still is called when I have player = new BattleMaster(); instead of calling BattleMaster.save();
I disagree. It is not. Here is some code in which I use player = new BattleMaster();
and you can see that when I call save on it, the Battlemaster save is called.

Don't forget that when you override a virtual function, it has to be the same. Same name. Same const on the end.

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
#include <iostream>

using std::cout;

class Character
{
     private:
          //A bunch of private member variables
     public:
          //Some other functions + constructor
          virtual void save() const = 0;
          virtual void attack(int blade, bool advan = false, bool disadvan = true) const = 0;
};

class Fighter : public Character
{
     private:
          //A few added member variables
     public:
          //A few added functions
          void save()
          {
               cout << "Fighter save";
          }
          void attack  (int blade, bool advan = false, bool disadvan = false) const {};
};

class BattleMaster : public Fighter
{
     private:
          //A few more member variables
     public:
          void save()  const { cout << "Battlemaster save";}
            
          void attack (int blade, bool advan = false, bool disadvan = false) const
          {
              
          }
};

int main()
{
     Character* player = new BattleMaster();
     player->save();
}


http://cpp.sh/5sxh
Last edited on
That being said, you can add in the keyword override to clearly show that the child is overriding a virtual parent method. If the parent didn't have this method, then it would be a syntax error, which could be useful at compile time.

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
#include <iostream>

using namespace std;

class Character
{
public:
    virtual void Save() = 0;
};

class Fighter : public Character
{
public:
    void Save() override
    {
        cout << "Fighter save\n";
    }
};

class BattleMaster : public Fighter
{
public:
    void Save() override
    {
        cout << "Battlemaster save\n";
    }
};

int main() 
{
    //Character c;  // Not allowed since all its methods are pure
    Fighter f;
    BattleMaster b;

    f.Save();
    b.Save();

    return 0;
}


Fighter save
Battlemaster save
@icy1 Right I was trying to replace what I believed was unimportant with psuedocode.

A simpler example that will compile but still shows my problem:
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
#include <iostream>
class Character
{
     private:
          std::string name;
     public:
          Character(std::string CharName)
          {
               name = CharName;
          }
          virtual void explain() const = 0
          {
               std::cout << "I'm a character!";
          }
};

class Fighter : public Character
{
     private:
           int testvar;
     public:
          Fighter(std::string CharName, int var)
          {
               name = CharName;
               testvar = var;
          }
          void explain()
          {
               std::cout << "I'm a fighter!";
               Character::explain();
          }
};

class BattleMaster : public Fighter
{
     private:
           char testChar;
     public:
          BattleMaster(std::string CharName, int var, char character)
          {
               name = CharName;
               testvar = var;
               testChar = character;
          }
          void explain()
          {
               std::cout << "I'm a battlemaster!";
               Fighter::explain();
          }
};

int main()
{
     Character* player = new BattleMaster("Typical D&D Name", 5, 'p');
     player->explain();
     return 0;
}


I would need player.explain() to output
I'm a battlemaster!
Last edited on
virtual void explain() const = 0

That bit on the end, "= 0", specifies that the function is "pure virtual". It means that there will be NO IMPLEMENTATION provided, and that the class this belongs is abstract.

So this:
1
2
3
4
          virtual void explain() const = 0
          {
               std::cout << "I'm a character!";
          }

is completely nonsensical.

I already said, you're confusing "pure virtual" and "virtual".
When your parent class has this:
virtual void explain() const

and your child class has this
virtual void explain()
WITHOUT the const, then it's a completely different function and you're not overriding anything.

This, too, I already said.
A simpler example that will compile but still shows my problem


It DOESN'T compile.

http://cpp.sh/5lbgx
This compiles, and works.

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
#include <iostream>
class Character
{
     private:
          
     public:
     std::string name;
          virtual void explain() const = 0;
};

class Fighter : public Character
{
     private:
           int testvar;
     public:
          Fighter(std::string CharName, int var)
          {
               name = CharName;
               testvar = var;
          }
          void explain() const
          {
               std::cout << "I'm a fighter!";
          }
};

class BattleMaster : public Fighter
{
     private:
           char testChar;
     public:
          BattleMaster(std::string CharName, int var, char character) :
          Fighter(CharName, var)
          {
               testChar = character;
          }
          void explain() const
          {
               std::cout << "I'm a battlemaster!";
          }
};

int main()
{
     Character* player = new BattleMaster("Typical D&D Name", 5, 'p');
     player->explain();
     return 0;
}
Topic archived. No new replies allowed.