質問者
ローカルクラスのデバッグ

質問
-
Visual C++ 2008 Express Edition で以下のように関数内にローカルクラスを定義し、コンストラクタにブレークポイントを置いてデバッグ実行したところ、自動変数ウィンドウにthisはアドレスのみ表示され、メンバ変数の"_n"が表示されません。
ウォッチウィンドウに"_n"と入力すると、値の欄には"CXX0033: エラーです: OMF の型情報にエラーがあります "と表示されます。
Code Snippetvoid Hoge()
{
class Local
{
int _n;
public:
Local(int n)
{
_n = n;
}
~Local()
{
cout << _n << endl;
}
};
Local local(100);
}何か方法があるのでしょうか?
よろしくお願いします。
すべての返信
-
VS2005のC++でも症状は再現しています。
たぶん、以下の記事に類似した現象のようですが、正確に該当しているのかどうか・・・確証なし。解決策のところも、まだ、上手くいくことを確認できていません。
http://support.microsoft.com/kb/102697/en-us
----追記 確かに、関数の中にローカルにクラス定義を置いたときだけなわけですね・・・。以下なら、問題ナシ。
Code Snippetclass Local {
int _n;
public:
Local(int n) {
_n = n;}
~Local() {
cout << _n << "\n";}
};void Hoge() {
Local local(100);
} -
確かに、リンクした記事は、直接は該当しないかも・・・。ただ、開発環境の内部では何か関係があるのかなぁ、とも思いますが、想像の域を超えません。
で、「素直に・・・」については、まぁ、回避策としては良いのですが、
一般論としては、「ローカルにクラスを定義して使う」ということ自体は問題ない手法であって、これが容易にデバッグできないのは障害ではないかと・・・。フィードバックに上げてみられてはどうでしょう?
-----(追記です。)
呼び出し履歴を使って、呼び出し元に遡れば、オブジェクトのメンバー変数として値が読み取れますね。privateなメンバーであっても。
-
この件に関して、外池さんのおっしゃるようにフィードバックにあげておきました。
外池 さんからの引用 呼び出し履歴を使って、呼び出し元に遡れば、オブジェクトのメンバー変数として値が読み取れますね。privateなメンバーであっても。
実際のプログラムでは、以下のコードのような場合です。ローカルクラスは派生クラスであり、またクラスのインスタンスも関数を抜けても生きています。
Code Snippetclass UndoAction
{
...
virtual void Undo() = 0;
};class UndoManager
{
...
bool Undo()
{UndoAction* action;
...
action->Undo(); // <= 呼び出し元
return true;
}...
private:
vector<UndoAction*> _actions;
};
class Person
{
string _name;
public:
Person()
{
}
string Name() const
{return _name;
}
void Name(const string& name)
{
class NameUndoAction : public UndoAction
{
Person* _person;
string _oldName;
string _newName;
public:
NameUndoAction(Person* person, const string& newName)
: _person(person), _oldName(person->_name), _newName(newName)
{}
virtual void Undo()
{
_person->_name = _oldName;
}
virtual void Redo()
{
_person->_name = _newName;
}
};if (name.compare(_name) == 0)
return;UndoAction* action = new NameUndoAction(this, name);
undoManager.Commit(action); // undoManagerはグローバルとします。_name = name;
}
};