C++ 对远期申报感到困惑

C++ 对远期申报感到困惑,c++,forward-declaration,C++,Forward Declaration,我认为通过声明类播放器,我不会出现以下错误: #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; pub

我认为通过声明类播放器,我不会出现以下错误:

#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--;
    }
};
参见“玩家”声明

error C2027: use of undefined type 'Player

检查错误2027,似乎我必须在Cards类之前显式地拥有整个类,但我认为forward类声明将使它变得不必要。我如何设置它的是,Cards类由Player类创建并分配一个子类,并存储在Player类中。继承Cards类的子类将调用Player类的函数。我很难确定这2个类是不是互相识别类。

在这种情况下,C++类的前向声明只会告诉编译器,你使用的类型是一个类。 这对于标题通常很有用,因为您只需要知道类型是一个类。包含类的头将花费更多的编译时间

但是在实现中,它是不同的。对于forward类,编译器将不知道其成员、方法等

为此,需要包含类的头文件

例如,如果只有forward类,则无法执行以下操作:

error C2227: left of '->SetHealth' must point to ...
因为编译器无法知道
GetHealth
方法存在于
Player
类中,只有一个forward类


注意:当您使用头实现它时,
AssignOwner
方法可能也有问题。我对C++有点生疏,因为我大部分时间都在做C,但是我认为你应该只声明类头中的原型,在包含正确的头文件之后,在实现文件中实现实际方法。

向前声明允许你声明一个指针或引用一个类型,但要实际使用指针或引用,必须有完整的类定义。您还需要类类型的成员或局部变量的完整定义。

按照通常的命名约定,您不应该需要
类播放器的前向声明。
(该类播放器的接口可能在
Player.h
中定义,否?)“Player.h”现在我得到:1>Player.obj:error LNK2005:“void\uu cdecl CardSelection(class Cards**,int)”(?CardSelection@@YAXPAPAVCards@@H@Z)已在game1.obj 1>F:\game1\Debug\game1.exe中定义:致命错误LNK1169:找到一个或多个多重定义符号。我是否应该将子类从移动到实现文件?我可以在头中使用前向声明,然后在实现文件中使用include头,这可能会起作用。实际上,它现在起作用了我上面列出的错误实际上是由于一个函数在它不应该在的地方。谢谢
owner->GetHealth();