Game クラス関数で、境界クラスをスタックに割り当てています
void Game::loadContent()
{
Boundary b(this, body);
}
境界クラスには、メインの Game クラスへのポインターと剛体へのポインターがあります。ただし、それぞれに参照を使用する必要があるかどうかはわかりませんか? ここで明確にすることは、後で説明する理由のために役立ちます。
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 と呼ばれるすべてのゲーム オブジェクトの基本クラスから派生します。
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* が破棄され、仮想メソッドを呼び出そうとするとエラーが発生します。
削除と言うまで境界ポインタを保持したいと思います。Boundary をヒープに割り当てずにこれを行う方法はありますか?
編集
const& Gameの使用に関する提案に応えて
エンティティヘッダーを次のように変更する必要があるようです
Entity.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
の Game クラスのグローバル メンバーにアクセスできないようです。g_wireShapeDrawer
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 &
どうしてこれなの?