在c++的if语句上初始化构造函数后删除字符串

String removed after constructor initialize on if statement on C++

本文关键字:构造函数 删除 字符串 初始化 c++ if 语句      更新时间:2023-10-16

我在c++ (MVS 2010)上初始化一个名为ManageRenderListenerCommand的类时遇到了一个奇怪的行为。这是作为命令设计模式实现的,其中ManageRenderListenerCommand命令是具体命令之一。

调用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());
    }
}

如果你需要更多的细节,请告诉我。谢谢你的帮助。

你在使用一个悬空指针。您正在使用的对象构造创建一个临时对象,当完整表达式(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>代替command,而不是原始指针。

我认为你要做的是初始化一个命令,它在c'tor中接受一个字符串;你实际做的是强制命令是字符串本身的地址。您需要使用'new'操作符创建一个新对象,如果您已经匹配了命令的类型,您应该能够启动特定的命令并在c'tor中为其提供字符串,如:

command = new SomeICommand(ManageRenderListenerCommand(mObserverRegistry, mEngine, negotiatorEvent.getMessage());
相关文章: