запутался в предварительных декларациях - PullRequest
2 голосов
/ 23 ноября 2011
#pragma once
#include "Player.h"

class Player;
//class SmallHealth;

const int kNumOfCards = 3; //for Player class also
const int kCardLimit = 3;

class Cards
{
private:
protected:
    int turnsInEffect;
    Player *owner;
public:
    Cards()
    {turnsInEffect = 1;}
    void AssignOwner(Player &player)
    {
        owner = &player;
    }
    virtual void PlayCard()
    {}
    virtual ~Cards(void)
    {}

};

class SmallHealth : public Cards
{
public:
    void PlayCard()
    {
        turnsInEffect = 1;
        owner->SetHealth(owner->GetHealth() + 5);

        //check if health goes over
        if(owner->GetHealth() > owner->GetHealthLimit())
        {
            owner->SetHealth(owner->GetHealthLimit());
        }
        turnsInEffect--;
    }
};

Я думал, объявив класс Player, я не получу эти ошибки:

error C2027: use of undefined type 'Player

см. Объявление 'Player'

error C2227: left of '->SetHealth' must point to ...

Проверка на ошибку 2027, кажется, я должен явно иметь весь класс перед классом Cards, но я думал, что предварительное объявление класса сделает его ненужным. Я настроил это так, что класс Cards создается и присваивается подкласс классом Player и сохраняется в классе Player. Подклассы, которые наследуют класс Cards, будут вызывать функции класса Player. Мне тяжело убедиться, что 2 класса идентифицируют классы друг друга.

Ответы [ 2 ]

3 голосов
/ 23 ноября 2011

В этом случае предварительное объявление класса C ++ просто скажет компилятору, что тип, который вы используете, является классом.

Это часто полезно для заголовков, так как вам нужно только знать, что тип является классом. Включение заголовка класса заняло бы больше времени компиляции.

Но в реализации все по-другому. С классом forward, компилятор не будет знать о его членах, методах и т. Д.

Для этого вам нужно включить заголовочный файл класса.

Например, только с классом forward вы не можете сделать это:

owner->GetHealth();

Поскольку компилятор не может знать, что метод GetHealth существует в вашем классе Player, только с классом forward.

Обратите внимание, что у вас также может быть проблема в вашем методе AssignOwner, поскольку вы реализуете его, используя свой заголовок. Я немного заржавел на C ++, так как я делаю C большую часть времени, но я думаю, что вы должны попытаться объявить только прототип в заголовке класса и реализовать фактический метод в вашем файле реализации, после включения правильного заголовочный файл.

0 голосов
/ 23 ноября 2011

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

...