0

I was given an interface (game_manager) that I can write the method's body but cannot add anything to it. I need to get my superclass inputs from the interface.

I have a superclass called Game that inherits from game_manager.

game_manager.h : (interface)

class game_manager
{
public:
    void add_team_A_goalkeeper(int stamina, int dribble, int pass, int defend);
    void add_team_A_defender(int stamina, int dribble, int pass, int defend);
    void add_team_A_striker(int stamina, int dribble, int pass, int defend);
    void add_team_B_goalkeeper(int stamina, int dribble, int pass, int defend);
    void add_team_B_defender(int stamina, int dribble, int pass, int defend);
    void add_team_B_striker(int stamina, int dribble, int pass, int defend);
    void play();
    string get_result();
private:

};

class Game :

class Game : public game_manager
{
private:
    bool Awin;
    bool Bwin;

    std::string result;

    GoalKeeper AGoalKeeper;
    Defender ADefender;
    Striker AStriker;
    GoalKeeper BGoalKeeper;
    Defender BDefender;
    Striker BStriker;

public:

    void add_team_A_goalkeeper(int stamina, int dribble, int pass, int defend);
    void add_team_A_defender(int stamina, int dribble, int pass, int defend);
    void add_team_A_striker(int stamina, int dribble, int pass, int defend);
    void add_team_B_goalkeeper(int stamina, int dribble, int pass, int defend);
    void add_team_B_defender(int stamina, int dribble, int pass, int defend);
    void add_team_B_striker(int stamina, int dribble, int pass, int defend);
    void play();
    std::string get_result();
    void handle_encounter();
};

main:

    #include "game_manager.h"

    int main()
    {
        game_manager game = game_manager();
        game.add_team_A_goalkeeper(100, 10, 20, 65);
        game.add_team_A_defender(100, 20, 60, 80);
        game.add_team_A_striker(100, 70, 50, 30);
        game.add_team_B_goalkeeper(100, 50, 40, 50);
        game.add_team_B_defender(100, 85, 20, 90);
        game.add_team_B_striker(100, 50, 20, 10);
        game.play();
        std::cout << game.get_result();
    }

when I create a game_manager object I want it to make an object from Game and call the overridden methods from Game class. I don't know how to implement it.

right now I get this error:

 /tmp/ccN3ZkwD.o: In function `main':
game.cpp:(.text+0x1635): undefined reference to `game_manager::add_team_A_goalkeeper(int, int, int, int)'
collect2: error: ld returned 1 exit status
M12421K
  • 57
  • 1
  • 2
  • 13
  • I don't really understand. Why are you creating a `game_manager` when you want a `Game`? – super May 09 '19 at 15:19
  • to be honest I don't know why I need to do it either. In advanced programming course, they asked for implementing an interface so ,if they change the main with a test main, the program still works. some kind of introduction to API programming. they provided the game-manger header. – M12421K May 09 '19 at 15:23
  • Try `game_manager game = Game();` – Coral Kashri May 09 '19 at 15:33
  • @KorelK I still get "undefined refrence to" error – M12421K May 09 '19 at 15:40
  • @M12421K do you have a `Game.cpp` file with implementations of the functions in `Game.h`? And have you added in the `main.cpp` `#include "Game.h"`? – Coral Kashri May 09 '19 at 15:50
  • I first thought the problem was from my makefile so I copied all my codes into a single cpp file. – M12421K May 09 '19 at 15:55
  • game_manager methods doesn't have a body. how can I make it to override them from Game methods? – M12421K May 09 '19 at 15:56

3 Answers3

1

You should define a dummy body for the methods in class game_manager in order to avoid getting the undefined reference error. It can be something like:

void game_manager::add_team_A_goalkeeper(int stamina, int dribble, int pass, int defend) {}

void game_manager::add_team_A_defender(int stamina, int dribble, int pass, int defend) {}

void game_manager::add_team_A_striker(int stamina, int dribble, int pass, int defend) {}

void game_manager::add_team_B_goalkeeper(int stamina, int dribble, int pass, int defend) {}

void game_manager::add_team_B_defender(int stamina, int dribble, int pass, int defend) {}

void game_manager::add_team_B_striker(int stamina, int dribble, int pass, int defend) {}

As mentioned by @KorelK instead of creating a game_manager object, you should create a Game object and store it in a game_manager variable:

game_manager game = Game();

However, when you call game.add_team_A_goalkeeper(100, 10, 20, 65); or other game_manager methods, it will execute the game_manager's dummy methods. In order to call the Game's methods, you will need to store the game_manager object to the Game pointer and call the function from that pointer:

game_manager game = Game();
Game * game_ptr = (Game *) &game;
game_ptr->add_team_A_goalkeeper(100, 10, 20, 65);

This is a rather hacky approach but since the assignment requires the game variable type to be game_manager, this is the only approach I can think of. :)

VietHTran
  • 2,233
  • 2
  • 9
  • 16
1

I think what they expected you to do is

game_manager *game = new Game();

and then do a bunch of game->add_XXX calls. That's the textbook example of using a concrete class via its interface. But that only would work if the functions were declared virtual in the game_manager class; they're not.

Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
  • Except the interface omitted declaring `virtual` methods, or pure `virtual` methods. Very odd. – Eljay May 09 '19 at 17:00
  • Right... Why does the OP need the Game class at all, then? – Seva Alekseyev May 09 '19 at 17:06
  • @M12421K • I suspect you are being taught "how to program in C++ poorly". If you are using a website, I'd consider alternatives. If you are in a class, my sympathies. If it is from a book, consider one of these good books: https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – Eljay May 09 '19 at 17:11
1

All you need to to is to use virtual functions in your interface.

class inter {
public:
    virtual void interface_function() = 0; // Pure virtual function
    virtual void interface_function2() { // Virtual function
        cout << "I am ***inter***::interface_function2" << endl;
    }
};

class use_inter : public inter {
public:
    void interface_function() { // Override inter::interface_function
        cout << "I am use_inter::interface_function" << endl;
    }
    void interface_function2() { // Override inter::interface_function2
        cout << "I am use_inter::interface_function2" << endl;
    }
};

class use_inter2 : public inter {
public:
    // Because we don't override a pure virtual function, this class is abstract too.
};

class use_inter3 : public inter {
public:
    void interface_function() { // Override inter::interface_function
        cout << "I am use_inter3::interface_function" << endl;
    }
    // Here we don't override a regular virtual function, so in call from this object type to "interface_function2", the implementation of inter::interface_function2 will be execute.
};

int main() {
    use_inter ui1;
    //use_inter2 ui2; // Compiler error: use_inter2 is an abstract class.
    use_inter3 ui3;
    ui1.interface_function(); // Prints: I am use_inter::interface_function
    ui3.interface_function(); // Prints: I am use_inter3::interface_function
    ui1.interface_function2(); // Prints: I am use_inter::interface_function2
    ui3.interface_function2(); // Prints: I am ***inter***::interface_function2

    cout << endl << "==============================" << endl << endl;

    inter *interface = new use_inter();

    interface->interface_function(); // Prints: I am use_inter::interface_function
    interface->interface_function2(); // Prints: I am use_inter::interface_function2

    delete interface;

    cout << endl << "==============================" << endl << endl;

    interface = new use_inter3();

    interface->interface_function(); // Prints: I am use_inter3::interface_function
    interface->interface_function2(); // Prints: I am ***inter***::interface_function2

    delete interface;
    return 0;
}

----- Output:

I am use_inter::interface_function
I am use_inter3::interface_function
I am use_inter::interface_function2
I am ***inter***::interface_function2

==============================

I am use_inter::interface_function
I am use_inter::interface_function2

==============================

I am use_inter3::interface_function
I am ***inter***::interface_function2
Coral Kashri
  • 3,436
  • 2
  • 10
  • 22