クラスインスタンスの呼び出しがおかしい – プログラミング – Home

クラスインスタンスの呼び出しがおかしい
 
通知
すべてクリア

[解決済] クラスインスタンスの呼び出しがおかしい


Sana
 Sana
(@Sana)
ゲスト
結合: 16年前
投稿: 2
Topic starter  

クラスの定義(?)でつまずいております。
現象で原因を探っておりますが
解決に至っておりません。

対処方法はあるのですが、それとは別に
どうして現状だめなのか、スルーしたくないので
ご教授いただければと思います。

template <class TBase /* = CWindow */>
class CWindowImplRoot : public TBase
{
...
};

template <class TBase = ATL::CWindow>
class CWindowImplBaseT : public CWindowImplRoot< TBase >
{
...
};

template <class T, class TBase /* = CWindow */>
class CWindowImpl : public CWindowImplBaseT< TBase>
{
HWND Create(){
/*ここでデバッグ*/
}
};

template <class T, class TBase = ATL::CWindow>
class CScrollWindowImpl : public ATL::CWindowImpl<T, TBase>,
public CScrollImpl< T >
{
...
};

class CViewWnd : public CScrollWindowImpl<CViewWnd>
{
int a;
int b;
ULONGLONG ull;
};

// CCommand,CMenu,CViewWnd等はそれぞれ子ウィンドウ

class COverlapWnd : public ....
{
CCommand m_Command;
CMenu m_Menu;
CViewWnd m_View;
CStatus m_Status;

OnCreate(){
m_Command.Create();
m_Menu.Create();
m_View.Create(); // ここ
m_Status.Create();
}
};

class CMain
{
COverlapWnd m_Wnd;

OpenOverlapWnd(){
m_Wnd.Create(...)
}
};

//
// エントリー
CMain g_Dlg;

int WinMain(){
g_Dlg.DoModal();
}

m_View.Create を呼び出すのですがCWindowImpl::Create上でのthisポインタの示す位置
がCViewWndメンバを含まずCWindowImplBaseTのみとなります。
そのためCWndBase::Create上の処理でCViewWnd(class T)への参照ができておらず正常
な処理が行われなくなります。
(場合によってはATL::CWindowのメンバも初期化されていません)

いろいろ変更するとthisポインタの示す位置は合っているがトレース上だけおかしかった
り、thisポインタ自体もずれていたりします。(定義の順番で変化するため等メモリ位置
が関係しているみたいなのですが…)

CCommand m_Command;
CMenu m_Menu;
CViewWnd m_View;
CStatus m_Status;

の定義順、上記メンバ変数削除等の操作により呼び出しが不正になったりします。
そもそも発端は、CViewWnd内の変数メンバ変数を増やしところ、この現象が発生するよう
になり、現在に至っておりますが原因が掴めておりません。

また、CViewWndの定義を一度クリアし、再度定義を追加していってどの部分が影響してい
るか確認したところint 変数はいくつ追加しても問題ありませんが、なぜかULONGLONG を
追加した時点でアウトのようです。

CViewWndをnewで作成する、またはCOverlapWndのスタティッククラスとして作成すると
問題がなくなり、ウォッチ上でもCViewWndおよびCWindowImplBaseTのthisポインタを示し
ています。

環境は VC2008 & WTL(SDK)です。


引用未解決
トピックタグ
wclrp ( 'o')
 wclrp ( 'o')
(@wclrp ( 'o'))
ゲスト
結合: 18年前
投稿: 287
 

俺の立場では他人のプログラムで起きている不思議な現象なんてわからんので
推測だよ。

デバッグ版ならエディットコンティニューになっている可能性があるな。
部分的にしかコンパイル・リンクしなおされていないのかもしれない。
変な時はリビルドしましょう。
エディットコンティニューはすごい便利なんだけど
メンバ変数追加しただけだと再コンパイルされないことがあるのさ。


返信引用
ISLe
 ISLe
(@ISLe)
ゲスト
結合: 18年前
投稿: 38
 

うちはエディットコンティニュー使って無いんですけど、依存関係データベース関連の
バグなのか必要なリコンパイルがされないことはよくありますね。


返信引用
Sana
 Sana
(@Sana)
ゲスト
結合: 16年前
投稿: 2
Topic starter  

wclrp ( 'o')さん、ISLeさん。ありがとうございます。

変数の追加、削除を行いトレースのthisアドレスを確認してふと見るとズレが4バイトの
場合があり、もしやと思い、全ソースの検索を行ったところ、
見事に#pragma pack(push, 1)に対するpopが抜けている箇所がありました(^^;;
パディングの絡みみたいだなぁとは思っていても、後に症状が出てくると、その時点では
他で変更してることに結びつきませんでした。

どおりでオブジェクトのアドレスにズレが生じていた訳で、現象から素直に考えてみたら
普通はこれに行き着き付くよなぁと思いつつ反省…。

大変お騒がせしました。ありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました