【问题标题】:Access outer object from inner object从内部对象访问外部对象
【发布时间】:2021-08-18 22:08:42
【问题描述】:

我在不同的文件中有 2 个(不完整的)类,Level 和 Object,看起来像这样

对象.h:

#pragma once
#include "Core.h"

class Object
{
public:
    Object(const Hitbox &hBox_, const Vector2& position_ = Vector2{0, 0}, const Vector2& velocity_ = Vector2{ 0, 0 });
    virtual Hitbox getHitbox();
    virtual void update();
    virtual void draw();
    virtual void drawHbox(const SDL_Color& color = SDL_Color{255, 0, 0, 255});
    static Core* core;
    

protected:
    Vector2 position;
    Vector2 velocity;
    Hitbox hBox;

};

Level.h:

#pragma once
#include "Object.h"

class Level
{
public:
    Level(const Vector2 &size_);
    void proceed();

    bool checkStaticCollision(Object* self);
    Object* checkBulletCollision(Object* self);

protected:
    std::vector<std::shared_ptr<Object>> objects;
    Vector2 size;

};

关卡保留所有对象,对象可以做一些独立的事情,比如绘制自身或接收输入,但对象也必须相互交互并做一些关卡的事情,比如碰撞、创建和删除自我、发射粒子等。我使对象可以访问级别?不完整的类型没有提供所需的功能,所以我不能只在 Object.h 中使用 class Level;,我不能简单地保留指向所需函数的指针,因为它们是类方法,如果我保留它而不使用 void*,那就太好了。

【问题讨论】:

  • 您的游戏是否保证一次只存在一个Level?如果是这种情况,那么在 app 单例中使用简单的 current_level 是一种非常简单有效的方法。
  • class Level; 在 object.h 中不需要,因为类 Object 的定义没有提到名称 Level。如果添加使用指针或引用Level 的成员函数声明,则class Level; 就足够了。在您的实现文件中,您需要 #include "level.h" 以便函数定义知道 Level 的样子。
  • 不,会有多个级别
  • 为什么在Object.h 中转发声明Level 不起作用?只要在Object.h 中只使用Level 的引用或指针,编译器就不需要知道LevelObject.h 中的类定义;假设这是您访问Level 成员的地方,那么在Object.cpp 中包含Level.h 就足够了。
  • 不,对象需要访问关卡功能。我已经用包含保护解决了它

标签: c++ class pointers header-files


【解决方案1】:

不确定这是否是最好的解决方案,但是,感谢@PeteBecker,我添加了(并且还发现了,呵呵)包括保护,所以现在看起来像这样:

对象.h:

#include "Core.h"

#ifndef OBJECT_H_
#define OBJECT_H_

#include "Level.h"

class Level;

class Object
{
public:
    Object(Level* level_, const Hitbox &hBox_, const Vector2& position_ = Vector2{0, 0}, const Vector2& velocity_ = Vector2{ 0, 0 });
    virtual Hitbox getHitbox();
    virtual void update();
    virtual void draw();
    virtual void drawHbox(const SDL_Color& color = SDL_Color{255, 0, 0, 255});
    static Core* core;
    

protected:
    Vector2 position;
    Vector2 velocity;
    Level *level;
    Hitbox hBox;

};

#endif

Level.h:

#include "Core.h"

#ifndef LEVEL_H_
#define LEVEL_H_

#include "Object.h"

class Object;

class Level
{
public:
    Level(const Vector2 &size_);
    void proceed();

    bool checkStaticCollision(Object* self);
    Object* checkBulletCollision(Object* self);

protected:
    std::vector<std::shared_ptr<Object>> objects;
    Vector2 size;

};

#endif

【讨论】:

  • Level.hObject的前向声明是不够的,因为你把它作为std::shared_ptr的类型参数需要知道Object的析构函数;我会在那里删除前向声明。我也看不出将#include "Core.h" 放在头后卫之外的意义;如果标头已经包含,编译器知道Core.h...的内容...
  • 替换#include "Core.h",谢谢。但是Level.h没有前向声明就无法编译,它返回syntax error: identifier 'Object'
猜你喜欢
  • 2021-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多