在 Game 类函数中,我将 Boundary 类分配给堆栈
void Game::loadContent()
{
Boundary b(this, body);
}
边界类有一个指向主游戏类的指针和一个指向刚体的指针。我不确定是否应该为每个使用参考?由于稍后解释的原因,这里的一些清晰度会有所帮助。
class Boundary : public DynamicEntity
{
public:
Boundary(Game *game, btRigidBody *body);
~Boundary(void);
// Override functions
virtual void draw(float dt);
virtual glm::vec3 getPosition();
virtual void update(float dt);
};
DynamicEntity 类分配主体并在其析构函数中处理指针删除。
class DynamicEntity : public Entity
{
public:
virtual ~DynamicEntity(void);
virtual void draw(float dt) = 0;
btRigidBody* getBody();
glm::vec3 getPosition() = 0;
virtual void update(float dt) = 0;
protected:
explicit DynamicEntity(Game *game, btRigidBody *body);
btRigidBody *m_body;
};
DynamicEntity.cpp 析构函数
DynamicEntity::~DynamicEntity(void)
{
m_game->m_dynamicsWorld->removeRigidBody(m_body);
delete m_body;
}
DynamicEntity 派生自所有名为 Entity 的游戏对象的基类
实体.h
class Entity
{
public:
// Make destructor virtual as this is a base class
virtual ~Entity(void);
virtual void draw(float dt) = 0;
int getID();
virtual glm::vec3 getPosition() = 0;
virtual void update(float dt) = 0;
protected:
explicit Entity(Game *game); // Abstract base constructor
Game *m_game;
int m_id; // Unique ID
};
我不能在此类的析构函数中对 Game 类指针调用 delete,但这就是为什么我不确定作为指针传递是否是正确的方法(而不是引用)?
Entity::~Entity(void)
{
// Derived class destructors are called first
delete m_game; // ERROR
}
Entity 类添加一个指向自身的指针,该指针可以通过 Game 类中的列表访问(对于在主 Game 类中迭代和调用 Entity 函数很有用)。
Entity::Entity(Game *game)
: m_game(game), // Initialise members
m_id(m_game->g_idGenerator->generateNewID()) // Generate unique ID
{
m_game->m_entities.push_back(std::shared_ptr<Entity>(this));
}
我遇到的主要问题是,一旦Game::loadContent()方法完成,就会为 Entity 类调用析构函数。这会破坏存储在列表中的 *shared_ptr*,并且在尝试调用任何虚拟方法时会发生错误。
我希望边界指针一直存在,直到我说删除。有没有办法在不将边界分配给堆的情况下做到这一点?
编辑
回应使用const& Game的建议
看来我必须将我的实体标头更改为以下
实体.h
#pragma once
#include <glm\glm\glm.hpp>
#include "Game.h"
// Forward declarations
class Game;
class Entity
{
public:
// Make destructor virtual as this is a base class
virtual ~Entity(void);
// '= 0' means pure virtual function (like 'abstract' in C#)
// This means they do not have to be declared in the source file '.cpp'
virtual void draw(float dt) = 0;
int getID();
virtual glm::vec3 getPosition() = 0;
virtual void update(float dt) = 0;
protected:
explicit Entity(const Game &game); // Abstract base constructor
Game m_game;
int m_id; // Unique ID
};
不是Game m_game
将 Game 类的实例分配给堆栈吗?如果它代表一个引用,它应该如何在标题中声明?
编辑 2
如果我在基实体类中存储对 Game 类的受保护引用,const Game &m_game
我似乎无法访问g_wireShapeDrawer
派生类中 Game 类的全局成员。
class Game
{
public:
GL_WireShapeDrawer g_wireShapeDrawer;
Game(void);
~Game(void);
void init();
void draw(float dt);
void handleInput(float dt);
void loadContent();
void update(float dt);
};
例如,尝试访问派生 Boundary 类源的 draw 方法中的全局成员时出现以下错误
void Boundary::draw(float dt)
{
m_game.g_wireShapeDrawer.drawPlane(glm::vec3(0, 1, 0), 0.0f, glm::vec4(1, 1, 1, 1));
}
错误 C2662:“GL_WireShapeDrawer::drawPlane”:无法将“this”指针从“const GL_WireShapeDrawer”转换为“GL_WireShapeDrawer &
为什么是这样?