4

ManageRenderListenerCommandというクラスをコンストラクターで初期化すると、C ++(MVS 2010)で異常な動作が発生します。これは、コマンド設計パターンとして実装されます。ここで、ManageRenderListenerCommandコマンドは具体的なコマンドの1つです。

私がManageRenderListenerCommandと呼ぶ場所

void Mediator::change(Negotiator* negotiator, NegotiatorEvent& negotiatorEvent){
    ICommand* command = NULL;
    if(negotiatorEvent.matchEvent("addToViewport")){
        command = static_cast<ICommand*> (&AddToViewportCommand(mCameraManager, mSceneCreator, mEngine));
    }else if (negotiatorEvent.matchEvent("manageRenderListener")){
        command = static_cast<ICommand*> (&ManageRenderListenerCommand(mObserverRegistry, mEngine, negotiatorEvent.getMessage()));
    }

    //Execute the created command
    if (command) command->execute();
}

コードでわかるように、ManageRenderListenerは文字列を受け取ります。この場合、この文字列には、NegotiatorEventクラス(negotiatorEvent.getMessage())に含まれる単語addが含まれます。

問題は、コンストラクターで、プライベートメンバーの文字列を取得することですが、デバッグの結果、アセンブリとキャストが削除され、「」に再初期化された後に確認できます。static_cast、dynamic_castを試しました。手がかりを与えるために、それは視界の問題だと思いますが、私はそれを管理する方法がわかりません。

}else if (negotiatorEvent.matchEvent("manageRenderListener")){
    //Here mMessage = ""
    command = static_cast<ICommand*> (&ManageRenderListenerCommand(mObserverRegistry, mEngine, negotiatorEvent.getMessage()));
    //Here mMessage is again "" instead of add
}

ManageRenderListener.cpp

#include "ManageRenderListenerCommand.h"

ManageRenderListenerCommand::ManageRenderListenerCommand(
    OgreRenderObserverRegistry* observerRegistry, 
    OgreEngine* engine,
    string message):
        mObserverRegistry(observerRegistry),
        mEngine(engine),
        mMessage(message){
}

void ManageRenderListenerCommand::execute(){
    if (mMessage.compare("add") == 0){
        mEngine->addRenderListener(mObserverRegistry->getCachedObserver());
    }else if (mMessage.compare("detach") == 0){
        mEngine->detachRenderListener(mObserverRegistry->getCachedObserver());
    }
}

詳細が必要な場合は、それを求めてください。ご協力いただきありがとうございます。

4

2 に答える 2

6

ダングリングポインタを使用しています。使用しているオブジェクト構造は一時オブジェクトを作成し、完全な式(static_cast)が終了すると破棄されます。あなたはまだそれがどこにあったか(で)へのポインタを持ってcommandいますが、オブジェクト自体はすでに破壊されています。

を呼び出すまでコマンドを持続させる方法でコマンドを作成する必要がありますexecute()。コードがあなたが示した通りであるならば、あなたは単にこれをすることができます:

if(negotiatorEvent.matchEvent("addToViewport")){
    AddToViewportCommand(mCameraManager, mSceneCreator, mEngine).execute();
}else if (negotiatorEvent.matchEvent("manageRenderListener")){
    ManageRenderListenerCommand(mObserverRegistry, mEngine, negotiatorEvent.getMessage()).execute();
}

作成との呼び出しの間にさらにステップがある場合は、execute()おそらくコマンドを動的に作成する必要があります。

void Mediator::change(Negotiator* negotiator, NegotiatorEvent& negotiatorEvent){
    ICommand* command = NULL;
    if(negotiatorEvent.matchEvent("addToViewport")){
        command = new AddToViewportCommand(mCameraManager, mSceneCreator, mEngine);
    }else if (negotiatorEvent.matchEvent("manageRenderListener")){
        command = new ManageRenderListenerCommand(mObserverRegistry, mEngine, negotiatorEvent.getMessage());
    }

    //Execute the created command
    if (command) command->execute();

    delete command;
}

C ++ 11にアクセスできる場合は、生のポインターの代わりにstd::unique_ptr<ICommand>forを使用してください。command

于 2013-03-25T08:43:33.377 に答える
1

あなたがやろうとしているのは、c'torで文字列を受け取るコマンドを初期化することだと思います。実際に行うことは、コマンドを文字列自体のアドレスにすることです。演算子「new」を使用して新しいオブジェクトを作成する必要があります。コマンドのタイプがすでに一致している場合は、コマンドを開始できるはずです。特定のコマンドを入力し、次のようにc'torの文字列を指定します。

command = new SomeICommand(ManageRenderListenerCommand(mObserverRegistry, mEngine, negotiatorEvent.getMessage());
于 2013-03-25T08:42:45.953 に答える