1

抽象的な Entity クラスにメインの Game クラスへのポインタを格納したいと思います。

Entity.h

#include "Game.h"

class Entity
{
public:
    Entity(Game* game);
    ~Entity(void);

    virtual void Draw(float dt) = 0;
    virtual void Update(float dt) = 0;          // '= 0' means pure virtual function (like 'abstract' in C#)

protected:
    Game* m_game;                               // Missing type specifier error C4430
};

エンティティ.cpp

#include "Entity.h"

Entity::Entity(Game* game)
{
    m_game = game;
}

Entity::~Entity(void)
{

}

次に、派生クラスをインスタンス化し、Game クラス参照をコンストラクターに渡して、それが格納されている基本クラスに渡すことができるようにする必要があります。

境界.h

#include "Entity.h"

class Boundary : public Entity
{
public:
    Boundary(Game* game);
    ~Boundary(void);

    // Override pure virtual functions
    void Draw(float dt);
    void Update(float dt);
};

Boundary コンストラクターは、参照された Game クラスを使用して、それ自体をリストに追加できます。

#include "Boundary.h"

Boundary::Boundary(Game* game) : Entity(game)
{
    // Add entity to the main entity list
    game->m_entities->push_back(*this);
}

Boundary::~Boundary(void)
{
}

void Boundary::Draw(float dt)
{
    // Call the base class as follows (C# equivalent: 'base.Draw(dt)')
    //Entity::Draw(dt);
}

void Boundary::Update(float dt)
{

}

これにより、次の 3 種類の問題が発生します。

game->m_entities->push_back(*this);

エラー C2663: 'std::list<_Ty,_Ax>::push_back': 2 つのオーバーロードには、'this' ポインターの有効な変換がありません

Game* m_game;Entity.hで

エラー C4430: 型指定子がありません - int と見なされます

list<Entity>* m_entities;Game.h で

エラー C2065: 'エンティティ': 宣言されていない識別子

Entity(Game* game);Entity.hで

エラー C2061: 構文エラー: 識別子 'ゲーム'

私が達成しようとしているものに相当するC#は次のとおりです。

public abstract class Entity
{
    protected Game game;

    public abstract void Draw(float dt);
    public abstract void Update(float dt);
}

public class Boundary : Entity
{
    public Boundary(Game game)
    {
        this.game = game;

        game.Entities.Add(this);
    }

    public override void Draw(float dt)
    {

    }

    public override void Update(float dt)
    {

    }
}

どこで間違ったのですか?

編集:

Game.h

#include "btBulletDynamicsCommon.h"
//#include "LinearMath\btQuaternion.h"
#include <list>

using namespace std;        // Required for list

class Entity;               // Forward declaration

class Game
{
public:
    list<Entity>* m_entities;

    Game(void);
    ~Game(void);

    void init();
    void draw(float dt);
    void loadContent();
    void update(float dt);

private:
    class btDefaultCollisionConfiguration* m_collisionConfiguration;
    class btCollisionDispatcher* m_dispatcher;
    class btDiscreteDynamicsWorld* m_dynamicsWorld;
    class btBroadphaseInterface* m_overlappingPairCache;
    class btSequentialImpulseConstraintSolver* m_solver;

    void exitPhysics();
    void initPhysics();
};

編集2:

私が今残されている唯一の問題は、コンストラクターでゲームを参照しようとすることです:

    Boundary::Boundary(Game *game) 
    : Entity(game)                  // Initialise base
{
    // Add entity to the main entity list
    game->m_entities->push_back(*this);      // ERROR
}

基本クラスは同じ問題に苦しんでいます

    Entity::Entity(Game* game) 
    : m_game(game)                  // Initialise members
{
    m_game->m_entities->push_back(this);     // ERROR here too
}
4

1 に答える 1

3

ポストエディット

Game.h の次の行:

list<Entity>* m_entities;

Entity インスタンスのリストへのポインターを宣言します。Entity の定義を確認するまでこのリストを使用できないという事実(これはここでは問題ではありません) とは別に、リストに追加したエンティティはすべてコピーされることも意味します。Entity のサブクラスを使用しているため、これによりオブジェクトがスライスされ、基本クラスの部分のみがコピーされます。したがって、リストは多態的ではありません。そして、境界 (またはその他のもの) を作成するたびに、エンティティ基本クラスのサブオブジェクトのみのコピーをリストに追加しようとします。

代わりにこれを考慮してください:

list<Entity*> m_entities;

push_backを基本クラスに移動することもできます。

Entity::Entity(Game *game) : m_game(game)
{
    game->m_entities.push_back(this);
}

Boundary::Boundary(Game *game) : Entity(game) {}

(そのため、サブクラスごとにコピーする必要はありません)。

一般に、ランタイム ポリモーフィズム(派生クラスと仮想関数) が必要な場合は、ポインターや参照などの間接化を使用する必要があります。ポインターを格納するようになったので、所有権と有効期間について考えるのも良い考えです (そのエンティティ リストに生のポインターではなくスマート ポインターを格納することから始めるのがよいでしょう)。

std::list<std::unique_ptr<Entity> > m_entities;

ああ、基本クラスの間接化 (ここのように) を介して派生型を削除する場合は、基本クラスのデストラクタも仮想として宣言する必要があります。


事前編集

型指定子が見つからないというエラーは、最初の手がかりです。Gameの定義で型指定子を参照すると、コンパイラは何が何であるかを判断できませんEntity

をインクルードGame.hしているため、そのヘッダーに問題があるか、循環依存関係があります (つまり、Game.hも含まれていますEntity.h)。

Game.hただし、そこに含める必要はまったくありません。

Entity.h

#ifndef USER1423893_ENTITY_H
#define USER1423893_ENTITY_H

class Game; // forward declaration

class Entity
{
public:
    virtual ~Entity(void);

    virtual void Draw(float dt) = 0;
    virtual void Update(float dt) = 0;

protected:
    explicit Entity(Game* game);

    Game* m_game;
};
#endif

エンティティ.cpp

#include "Entity.h"

Entity::Entity(Game* game) : m_game(game)
{
}

そのエラーを修正したらどうなりますか?

于 2012-08-22T22:34:19.973 に答える