子クラスから入力する変数を持つ親クラスがあります。しかし、実行時には、式が入力されていないようです。null でさえありません。IDE が「式を評価できません」と言うのは、ランダムなことです。初期化コードをステップ実行しましたが、常に正しく初期化されているようです。しかし、後で実行時にその変数を呼び出すと、手を空中に投げ出して、これが何であるかわからないと言います。
基本クラス:
namespace Events
{
class MessageReceiver;
class MessageJoint
{
public:
MessageJoint( Ogre::String id, MessageReceiver* receiver );
void FireEvent( MessageReceiver* from );
void SetData( boost::any d ){ data = d; }
void SetIdentifier( Ogre::String id ){ identifier = id; }
virtual void HandleEvent( boost::any ) = 0;
void TuneIn( MessageReceiver* r )
{
listeners.push_back( r );
}
Ogre::String GetIdentifier(){ return identifier; }
MessageReceiver* owner;
std::vector< MessageReceiver* > listeners;
boost::any data;
private:
Ogre::String identifier;
};
}
基本クラスを使用する子クラス:
class JointCloseMenu : public Events::MessageJoint
{
public:
static const Ogre::String cJointCloseMenuId;
JointCloseMenu( Events::MessageReceiver* receiver ) : Events::MessageJoint( cJointCloseMenuId, receiver ){}
void HandleEvent( boost::any );
#define JOINTCLOSEMENUNAME Ogre::String("JointCloseMenu")
};
こんな感じで初期化しています。識別子の値を 2 回設定していることがわかります。
Events::MessageJoint::MessageJoint( Ogre::String id, MessageReceiver* receiver )
: identifier( id ), owner(receiver), data( 0 )
{ SetIdentifier( id ); }
そして、これが爆発する関数です。MessageJoint::GetIdentifier に入り、その中で識別子が有効なメモリ アドレスではないことがわかります。IDE は、式を評価できないと言うだけです。
void Events::MessageJoint::FireEvent( MessageReceiver* from )
{
Ogre::String blah = GetIdentifier(); //<--KABOOM!!!!
Message m( from->GetMyAddress(), owner->GetMyAddress(), GetIdentifier(), &data );
EventManager::getInstance()->MessageDispatch( m );
//}
}
cJointCloseMenuId の初期化方法を説明するのを忘れていました。JointCloseMenu クラスの実装ファイルでは、次のように文字列の名前を初期化します。
const Ogre::String cJointCloseMenuId;