Как я могу создать объект суперкласса в классе интерфейса? - PullRequest
0 голосов
/ 09 мая 2019

Мне дали интерфейс (game_manager), который я могу написать тело метода, но не могу ничего добавить к нему.Мне нужно получить входные данные суперкласса из интерфейса.

У меня есть суперкласс, называемый Game, который наследует от game_manager.

game_manager.h: (интерфейс)

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:

};

класс 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();
    }

Когда я создаю объект game_manager, я хочу, чтобы он создал объект из Game и вызвал переопределенные методы из класса Game.Я не знаю, как это реализовать.

сейчас я получаю эту ошибку:

 /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

Ответы [ 3 ]

1 голос
/ 09 мая 2019

Я думаю, что они ожидали, что вы сделаете

game_manager *game = new Game();

и затем сделаете кучу game->add_XXX звонков.Это учебный пример использования конкретного класса через его интерфейс.Но это сработало бы, только если функции были объявлены virtual в классе game_manager;это не так.

1 голос
/ 09 мая 2019

Все, что вам нужно, - это использовать virtual функции в вашем интерфейсе.

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
1 голос
/ 09 мая 2019

Вы должны определить фиктивное тело для методов в классе game_manager, чтобы избежать получения неопределенной ошибки ссылки.Это может быть что-то вроде:

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) {}

Как упоминалось @KorelK, вместо создания объекта game_manager, вы должны создать объект Game и сохранить его в переменной game_manager:

game_manager game = Game();

Однако, когда вы вызываете game.add_team_A_goalkeeper(100, 10, 20, 65); или другие методы game_manager, он будет выполнять фиктивные методы game_manager.Чтобы вызвать методы Game, вам нужно сохранить объект game_manager в указателе Game и вызвать функцию из этого указателя:

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

Это довольно хакерскийподход, но так как для присваивания требуется, чтобы тип переменной game был game_manager, это единственный подход, который я могу придумать.:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...