String removed after constructor initialize on if statement on C++
c++, constructor, initialization, scope, string
Solution
Yo're using a dangling pointer. The object construction you're using creates a temporary object, which is destroyed when the full expression (the `static_cast`) ends. You still have a pointer to where it was (in `command`), but the object itself has already been destroyed.
You need to create the command in a way to have it persist until in call to `execute()`. If the code is as you've shown, you could simply do this:
if(negotiatorEvent.matchEvent("addToViewport")){
AddToViewportCommand(mCameraManager, mSceneCreator, mEngine).execute();
}else if (negotiatorEvent.matchEvent("manageRenderListener")){
ManageRenderListenerCommand(mObserverRegistry, mEngine, negotiatorEvent.getMessage()).execute();
}
If there are more steps in between the creation and the call to `execute()`, you will probably have to create the command dynamically:
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;
}
If you have access to C++11, use `std::unique_ptr<ICommand>` for `command` instead of a raw pointer.
Problem
I'm experiencing a extrange behaviour on C++ (MVS 2010) when initializing on constructor a class called ManageRenderListenerCommand. That is implemented as a Command design patter, where ManageRenderListenerCommand command is one of the concrete commands. The place I call 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(); } ``` As you can see in the code, ManageRenderListener receives a string, in that case this string contains the word add that is contained on the NegotiatorEvent class (`negotiatorEvent.getMessage()`). The problem is, on the constructor, I take the string on an private member, but debugging I can see after the assgnation and casting it is removed and reinitialized to "". I have tried static_cast, dynamic_cast. To give a clue, I think it's a visibility problem but I don't know how to manage it. ``` }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()); } } ``` If you need more details ask for it. Thanks for your help.