【问题标题】:C++ class declaration after using it使用后的 C++ 类声明
【发布时间】:2022-06-03 05:55:27
【问题描述】:

我想用一个链接到稍后声明的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){

【问题讨论】:

  • 请注意,您应该通过引用获取参数(或者在某些情况下是指向它的指针) - 复制 target 不太可能是您想要的
  • @UnholySheep 的好评论。我可以建议您阅读 Marc Gregoire 的“Professional C++”或任何其他可能更基础的 C++ 书籍 - 但这是最​​新的,即在过去两年中出版并涵盖 C++20。跨度>
  • 您可以将Entity 替换为auto,即使这样的代码看起来很难看。

标签: c++ class header-files declaration


【解决方案1】:

问题是编译器不知道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){
            
        };
};

Working demo

方法二

解决这个问题的另一种方法是,您可以在类内部只提供成员函数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)
{
    
}

Working demo

【讨论】:

    【解决方案2】:

    你不能。

    您必须提前声明。但是,在某些情况下,您可以稍后定义它。

    要转发声明一个类,请在使用前写下:

    class Entity;
    

    【讨论】:

      【解决方案3】:

      在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,你可以定义一个可攻击的概念,使实体是可攻击的,我很喜欢。

      【讨论】:

        猜你喜欢
        • 2020-07-19
        • 1970-01-01
        • 2012-06-22
        • 1970-01-01
        • 2018-08-13
        • 2021-06-03
        • 1970-01-01
        • 1970-01-01
        • 2014-07-10
        相关资源
        最近更新 更多