使用后的C++类声明

问题描述 投票:0回答:3

我想创建一个带有参数的方法,该参数链接到稍后声明的

Enemy
。 这是我的代码:

#include <iostream>
#include <vector>
using namespace std;
class Weapon{
    public:
        int atk_points;
        string name;
        string description;
        void Attack(Entity target){
            
        };
};
class Armor{
    public:
        int hp_points;
        string name;
        string description;
        int block_chance;
};
class Entity{
    public:
        int hp;
        int atk;
        string name;
        vector<Weapon> weapons;
        vector<Armor> armors;
};

我试图寻找答案,但没有找到任何帮助。 这是错误日志:

prog.cpp:9:15: error: ‘Entity’ has not been declared
   void Attack(Entity target){
c++ class header-files declaration
3个回答
5
投票

问题是编译器不知道在您用作参数类型的地方

Entity
是什么。所以你需要告诉编译器
Entity
是一个类类型。

有两种方法可以解决这个问题,下面给出了两种方法:

方法一

解决这个你需要做下面给出的两件事:

  1. 为班级提供前瞻性声明
    Entity
    .
  2. 使
    Attack
    的参数成为引用类型,这样我们就可以避免不必要的复制参数,而且因为我们提供了成员函数的定义而不仅仅是声明。
class Entity; //this is the forward declaration
class Weapon{
    public:
        int atk_points;
        string name;
        string description;
//------------------------------v------------>target is now an lvalue reference
        void Attack(const Entity& target){
            
        };
};

工作演示

方法二

解决这个问题的另一种方法是,您可以只在类内部提供成员函数

Attack
'的声明,然后在类
Entity
的定义之后提供定义,如下所示:

class Entity;   //forward declaration
class Weapon{
    public:
        int atk_points;
        string name;
        string description;
//------------------------------v----------->this time using  reference is optional
        void Attack(const Entity& target);  //this is a declaration
};
//other code here as before


class Entity{
    public:
        int hp;
        int atk;
        string name;
        vector<Weapon> weapons;
        vector<Armor> armors;
};

//implementation after Entity's definition
void Weapon::Attack(const Entity& target)
{
    
}

工作演示


1
投票

你不能。

必须早点申报。但是,在某些情况下,您可以稍后定义它。

要转发声明一个类,在使用之前写这个:

class Entity;

0
投票

在c++中,这样的代码无法编译:

class A {
    void fooa(B) {}
};

class B {
    void foob(A) {}
};

但是这样的代码是可以编译的,我们可以顺便改一下代码:

class A { };
class B { };
void fooa(A *, B) {}
void foob(B *, A) {}

它有效,没有什么是递归的。

所以,我认为更改参考不是一个好主意。直接的方法就是使用一些技巧。例如,将

Entity
更改为
auto
。像那样:
void Attack(auto target)
。 更重要的是,用c++20,你可以定义一个可攻击的概念,让实体是可攻击的,我很喜欢。

© www.soinside.com 2019 - 2024. All rights reserved.