2016-03-28 6 views
0

Edit:Объект нарезка: Доступ dervied методы класса от базового класса объекта

  1. Проблема заключается в файле GoFish.h, в конструктор к быть конкретным, когда он пытается создать экземпляр объекта игроков.

  2. Компилятор не выдает следующее сообщение об ошибке: не член с именем «noOfBooks» в «Игрок»

GoFish() {players = new GoFishPlayer[2];} // Instantiate two players 

Объект нарезка, кажется, один из самых неоднозначных понятий в ООП для начинающих. Я работаю над этой карточной игрой на C++, где у меня есть базовый класс: Игрок и производный класс GoFishPlayer. При попытке получить доступ к методам объекта GoFishPlayer, ссылающимся на объект Player, программа имеет тенденцию отсекать определенные методы и атрибуты для производного класса, тем самым делая его клоном базового объекта. Есть ли способ преодолеть эту проблему?

Game.h

Абстрактный класс игры: который формирует основу для обеих игр - GoFish и CrazyEights

class Game { 

protected: 
Deck* deck; 
Player* players; 
int player_id; 

public: 
Game(){ 
    deck = Deck::get_DeckInstance(); // Get Singleton instance 
    player_id = choosePlayer(); 
    players = NULL; 
} 
.... 
} 

GoFish.h

производный класс GoFish - Проблема здесь в конструкторе, когда я пытаюсь создать экземпляр объекта игрока, полученный из класса Game

class GoFish : public Game{ 

static GoFish* goFish; 
GoFish() {players = new GoFishPlayer[2];} // Instantiate two players 

public: 
static GoFish* get_GoFishInstance() { 
    if(goFish == NULL) 
     goFish = new GoFish(); 

    return goFish; 
} 

Player.h

class Player{ 

protected: 
std::string playerName; 
Hand hand; 
bool win; 

public: 
Player(){ 
    playerName = "Computer"; // Sets default AI name to Computer 
    hand = Hand(); // Instatiate the hand object 
    win = false; 
} 
.... 

GoFishPlayer.h

class GoFishPlayer : public Player { 

private: 
std::vector <int> books; 
int no_of_books; 

public: 
GoFishPlayer() { 
    no_of_books = 0; 
    books.resize(13); 
} 

int noOfBooks(){return no_of_books;} 
void booksScored() {no_of_books++;} 

bool checkHand() {} 
.... 
+1

Это много кода - на что мы на самом деле должны смотреть? –

+0

где ваш код, который вызывает клонирование объектов? –

+1

Это указатели - там нет нарезки. –

ответ

0

формулировка вашего вопроса кажется неоднозначным для меня, но как лучше, как я понимаю, вы пытаетесь получить доступ к методам GoFishPlayer через ссылку на Player объекта? Это не проблема, вызванная срезанием объектов, это то, как работает полиморфизм.

Вам необходимо указать ссылку на объект Player, чтобы он стал ссылкой на объект GoFishPlayer.

class Parent 
{ 
    public: 
     void foo() { std::cout << "I'm a parent" << std::endl; } 
}; 

class Derived : public Parent 
{ 
    public: 
     void bar() { std::cout << "I'm a derived" << std::endl; } 
}; 


int main() 
{ 
    Derived d; 

    // reference to a derived class stored as a prent reference 
    // you can't access derived methods through this 
    Parent& p_ref = d; 
    // this won't work 
    // p_ref.bar(); 

    Derived& d_ref = static_cast<Derived&>(p_ref); 
    // this works 
    d_ref.bar(); 
} 

Это работает только если вы точно знаете, что на самом деле p_ref типа Derived, или что такого типа, который наследует от Derived. Если вы не можете быть уверены, что вам нужно выполнить проверку времени выполнения, используя dynamic_cast, а затем поймайте любые std::bad_cast исключения, которые были выбраны.

+0

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

+0

Иногда это неизбежно, хотя в таких ситуациях я бы предпочел, чтобы база реализовала полный интерфейс с виртуальными методами, чтобы там нет необходимости в dynamic_cast. – Fibbles

Смежные вопросы