0

私は遭遇したトリッキーな小さな問題を抱えています。問題は私が物を投げる方法に関係していると思います。

だから私はという基本クラスを持っていcombatEntityます。以下の機能があります

class combatEntity {
public:
    virtual void update();
};

次に、から派生したクラスmobがありcombatEntity、更新関数をオーバーライドします。

class mob : public combatEntity {
public:
    virtual void update();

}

monster次に、update関数から派生しmob、update関数をオーバーライドするという名前のクラスがあります。

class monster: public mob {
public:
    virtual void update();
}

私はcombatEntityポインタを持っていますi

combatEntity* i;

で、〜がある:

//returns a mob* pointer (needs explicit cast)
monster* newMonster = getMob();
i = newMonster;

getMob()機能:

mob* getMob() {
   mob* newMob = new mob();
   //set some data in newMob
   return newMob;
}

を呼び出すとi->update()、「new mob();」に設定されているmob::update()ため、新しいmobポインタを返すため、を呼び出します。を呼び出すときは、呼び出す必要がありますが、ブレークポイントを使用すると、呼び出しではなく呼び出しであることがわかります。newMonstergetMob()i->update()monster::update()mob::update()monster::update()

したがって、新しいmonsterオブジェクトを作成する必要がありますが、それでも、から返されたオブジェクトで基本クラスデータが満たされていますgetMob()が、関数は適切にオーバーライドされています。dynamic_cast、static_cast、reinterpret_castも試しましたが、どれも機能していないようです。または、派生クラスで関数を適切にオーバーライドしながら、基本クラスを派生クラスにキャストする必要があります。

うまくいけば、これは意味を成します。何かアドバイスをいただければ幸いです。

4

3 に答える 3

2

階層ツリーを見て、クラスがあなたの考え方に関連していることを確認してください。

このコード

#include <iostream>

struct combatEntity
{
    virtual void Update() { std::cout << "Combat Entity\n"; };
};

struct mob : combatEntity
{
    virtual void Update() { std::cout << "Mob\n"; };
};

struct monster : mob
{
    virtual void Update() { std::cout << "Monster\n"; };
};

int main(int argc, char **argv)
{
    combatEntity *ce = new monster;
    ce->Update();
    delete ce;

    return 0;
}

この出力を作成します:

Monster

出典: http: //ideone.com/k6LAB

于 2012-09-05T07:59:59.950 に答える
0

あなたのライン

monster* newMonster = getMob();

コンパイルしないでください。私は得る

error: invalid conversion from ‘mob*’ to ‘monster*’ [-fpermissive]

(また、あなたの行i = monster;はおそらく読むべきi = newMonster;です)。これがすべてを説明していると思います(Luchianからのコメントも参照してください)。

于 2012-09-05T07:49:30.810 に答える
0

仮想を使用しているので、ポインタを何として宣言しても、「update」は常に正しい関数を呼び出します。これが「仮想」の仕組みです。

オブジェクト自体ではなく、ポインタが呼び出されるものを決定するようにしたい場合は、それらを非仮想にします。この場合、pointer-typeは、どの「更新」が呼び出されるかを決定します。

両方が必要な場合でも、単に更新するのではなく、monster :: update()のようなものを呼び出すことができます。ただし、(スーパークラスの実装を呼び出すために)派生クラスの更新関数内からこれを実行しない限り、継承階層を通過しようとすると、設計が不適切である可能性があります。

于 2012-09-05T07:53:31.717 に答える