我正在移植 C++/WTL项目从 Visual Studio 2005 到 VS 2008。项目配置之一是单元测试构建,它定义了预处理器符号 UNIT_TEST。
为了让我的 WTL 类进入我的测试工具,我做了一个 CFakeWindow
stub 所有 CWindow 方法的类。然后在我的 stdafx.h 文件中,我在导入 atlwin.h(定义 CWindow 类)的下方执行此操作:
#ifdef UNIT_TEST
#include "fakewindow.h"
#define CWindow CFakeWindow
#endif
我的窗口类看起来像这样:
class CAboutDialog :
public CDialogImpl< CAboutDialog, CWindow >
, public CDialogResize< CAboutDialog >
{
// class definition omitted...
};
这在 VS 2005 中效果很好。问题是在 VS 2008 中,调用的是原始 CWindow 类的方法,而不是 CFakeWindow 类。这当然会导致测试失败,因为 CWindow
撒上ATLASSERT(::IsWindow(m_hWnd))
.
当我在调试器中逐步执行代码时,我看到 CAboutDialog 类继承自 CDialogImpl<CAboutDialog, CFakeWindow>
.然而,当我在 CAboutDialog
上调用方法时(例如 EndDialog(code)
), CWindow
正在调用方法。
这是 VS 2008 中的错误,还是我的条件模板继承技术是 VS 2005 允许但 VS 2008“修复”的可憎行为?是否有解决方法,或者我是否需要考虑一种不同的技术来对 WTL 类进行单元测试?我真的很喜欢这种技术,因为它让我可以将 WTL 类放入测试工具中,而无需处理 WTL 库。
编辑:正如下面对 Conal 的回复中所述,预处理器输出显示我的类继承自 CFakeWindow:
class CAboutDialog :
public CDialogImpl<CAboutDialog, CFakeWindow >
, public CDialogResize< CAboutDialog >
...
如上所述,当我在调试器中单步执行代码时,CAboutDialog 在本地窗口中显示为继承自 CFakeWindow。
编辑 2:按照 Conal 的建议,我逐步进行了反汇编,代码应该调用 CFakeWindow 方法,但实际调用的是 CWindow 方法。
if ( wID == IDCANCEL )
00434898 movzx edx,word ptr [ebp+8]
0043489C cmp edx,2
0043489F jne CAboutDialog::OnCloseCmd+90h (4348B0h)
{
EndDialog( wID ) ;
004348A1 movzx eax,word ptr [ebp+8]
004348A5 push eax
004348A6 mov ecx,dword ptr [ebp-10h]
004348A9 call ATL::CDialogImpl<CAboutDialog,ATL::CFakeWindow>::EndDialog (40D102h)
}
else
004348AE jmp CAboutDialog::OnCloseCmd+9Ah (4348BAh)
{
EndDialog(IDOK);
004348B0 push 1
004348B2 mov ecx,dword ptr [ebp-10h]
004348B5 call ATL::CDialogImpl<CAboutDialog,ATL::CFakeWindow>::EndDialog (40D102h)
我开始更倾向于 VC++ 2008 调试器中的错误。
最佳答案
这可能是一种更清晰的处理方式:
#ifdef UNIT_TEST
#include "fakewindow.h"
#define TWindow CFakeWindow
#else
#define TWindow CWindow
#endif
也许存在重新定义未通过预编译 header 的情况。如果是这样,这将捕获任何此类问题。
关于c++ - Visual Studio 2008 c++ 条件模板继承错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1619989/