-1

For my Intro to CS class we're making a short game where the different characters have to fight each other (attack points and defense points are generated by rolling a certain number of dice). One of the characters is a Shadow which overrides the base class defense function in order to generate a 50% chance of not being hit. I tested the overridden function in isolation and it works but when I call it in my combat function it just used the base class version of defense, despite the fact that the character playing is a Shadow. Any ideas? I suspect it has something to do with pointers. And yes the base class defense function is declared as virtual.

Update: Here is the base class and shadow class -- I removed member data and functions that are not relevant to the question.

  //The Character Class
   class Character
  {
    protected:
    Dice AttackDie;
    Dice DefenseDie;

public:
    //The Constructor
    Character(string,int,int,int,int,int,int);
    virtual int attack();
    virtual int defend() const;   //I've tested it with and without const, it still doesn't work
    int getSP();   //StrengthPoints Accessor
    string getName();
    friend void combat(Character, Character);  
};

//Shadow subclass
class Shadow: public Character
{
   //Will override defense
    public:
    Shadow(string,int,int,int,int,int,int);

    //Override the defense function
    int defend() const;
};

 void Combat(Character char1, Character char2)
{

    //Set up the players so that they can alternate
    Character* player1 = &char1;
    Character* player2 = &char2;

    //While loop for combat;
   while (char1.getSP() > 1 || char2.getSP() > 1)   //Play until a character dies
   {

      //Variables for combat
      int attacksum = 0;
      int defensesum = 0;
      int result = 0;
      int damage = 0;
      int hurt = 0;

      attacksum = player1->attack(); //Generate attack value

      //Generate Attack Points
      cout << player1->getName() << " attack points are " << attacksum <<   endl;

    //Generate Defense Points --- This does not call the overriden function when player2 is a Shadow
      defensesum = player2->defend();    //Generate defense value

    //Display the defeense
      cout << player2->getName() << " defense points are " << defensesum << endl;

}
user2466886
  • 205
  • 1
  • 3
  • 14
  • Please show the `Character` and `Shadow` classes. – Thomas Matthews Feb 13 '15 at 18:53
  • You better should show how the `Character` function actually was _"overridden"_ instead of showing the calling code. That's not helpful to solve your question. Most Probably you're simply missing a `virtual` keyword in the base class. – πάντα ῥεῖ Feb 13 '15 at 18:55
  • Hazarding a guess, I'd say that the function needs [to be marked `virtual`](http://www.learncpp.com/cpp-tutorial/122-virtual-functions/) – Conduit Feb 13 '15 at 18:55
  • `base class defense function is declared as virtual.` That is not enough. The parameter types for the override function must match, and it sounds like this is the issue. Please post the classes, as others have already stated in the comments. – PaulMcKenzie Feb 13 '15 at 18:57
  • Adding to the comment by @PaulMcKenzie - if you are using C++11, you can defensively code for precisely the problem mentioned. Mark the subclass' function with `override` like this: `virtual void foo() override;`. This will throw a compiler error if the signature doesn't match that of the base class. – Conduit Feb 13 '15 at 19:00
  • Please post how you're calling this function. The function you posted consists solely of `Character` types, and gives no indication of any derived class usage in terms of how it's called and what the parameters you're calling with are. – PaulMcKenzie Feb 13 '15 at 19:05
  • You have a slicing problem. Your `Combat` function takes `Character` by value when it should be by reference or pointer. [Here's a post that explains it.](http://stackoverflow.com/questions/274626/what-is-object-slicing) – David G Feb 13 '15 at 19:05
  • Yup it was a slicing issue, now it's being called correctly. – user2466886 Feb 13 '15 at 19:19

1 Answers1

0

Make sure your method signature is the same (same return value, same parameters) and make sure the function is marked virtual.

You can troubleshoot a little using the idea posted here:

Safely override C++ virtual functions

Or for further troubleshooting you can write your base method as:

virtual void baseMethod() = 0;

If you don't override it correctly, your compiler should throw an error.

Community
  • 1
  • 1
Diniden
  • 1,005
  • 6
  • 14