我正在将一个应用程序从Visual C ++ 6.0移植到VC ++ 2008中的MFC版本,它上面有很多get - AfxGetMainWnd()
- 和 - 做 - C-Style-casts: / p>
CUserInterfaceDoc *m_pDoc = (CUserInterfaceDoc*)((CFrameWnd *)AfxGetMainWnd())
->GetActiveDocument();
当我尝试上述步骤时,只需转换为dynamic_cast<>
,我发现在我的程序中,不再可以通过转换为CUserInterfaceDoc
来访问主窗口。我想也许MFC在VC ++ 6中滥用了强制转换,或者编译器做了一些魔术。
重写上面的内容以使用动态强制转换就像这样,最后会出现一个nil指针,它会使我在这里写的assert()条件跳转,正如我想要的那样:
CUserInterfaceDoc *m_pDoc;
CWnd * mainWnd = AfxGetMainWnd();
assert(mainWnd);
CFrameWnd *frmWnd = dynamic_cast<CFrameWnd *> (mainWnd);
assert(frmWnd);
m_pDoc = dynamic_cast<CUserInterfaceDoc *> (frmWnd);
assert(m_pDoc);
我假设之前完成此操作的所有人都能说“是的,当然,他们改变了这种投射行为......”但是我找不到它的文档。
在可能的情况下,我正在改变我的C ++类,以便在我存储的情况下使用成员变量(字段)
通过从“或多或少全球化”AfxMainWnd()
走下来,链接到它以前发现的事物。
这会帮助我知道发生了什么变化,所以我可以理解上面发生了什么。
CUserInterfaceDoc
是我的应用程序的MFC C ++ Document类,它是一个COleServerDoc,它曾经在运行时“可查找”,顶部有粗略的C风格。
上面的演员程序仍然在现代C ++中编译,但它已经破碎了,可能是由于旧的VC ++ 6编译器使用C风格的演员表符合ISO C ++标准做了某种内部“魔术”。 (这纯粹是我的猜测。)
我的问题分为两部分:
从另一个当前没有引用主CFrameWnd的类中获取CurrentDocument(CFrameWnd :: CurrentDocument)并使用我在此问题顶部显示的hack的常用方法是什么?
非ISO兼容的VC ++ 6与或多或少符合ISO标准的后续C ++版本之间发生了什么变化,这些版本会改变上面的强制转换表达式的行为,或者由于MFC内部而发生破坏架构变化?
我的代码更改:
CUserInterfaceDoc * CMyBrowser::GetUserInterfaceDoc()
{
CUserInterfaceDoc *m_pDoc;
// formerly did this, which works in VC++6 and doesn't work anymore:
//m_pDoc = (CUserInterfaceDoc*)((CFrameWnd *)AfxGetMainWnd())->GetActiveDocument();
assert(m_pMainFrm);
m_pDoc = dynamic_cast<CUserInterfaceDoc *> ( m_pMainFrm->GetActiveDocument() );
assert(m_pDoc);
}
答案 0 :(得分:4)
如果你正在使用MFC,你可能只是咬紧牙关并使用DYNAMIC_DOWNCAST这是一个MFC定义的宏来进行投射,它基本上等同于dynamic_cast。
CFrameWnd* pFrm = DYNAMIC_DOWNCAST(CFrameWnd, AfxGetApp()->m_pMainWnd);
m_pDoc = DYNAMIC_CAST(CUserInterfaceDoc, m_pMainFrm->GetActiveDocument());
答案 1 :(得分:1)
在你的第一次改写中:
CUserInterfaceDoc *m_pDoc;
CWnd * mainWnd = AfxGetMainWnd();
assert(mainWnd);
CFrameWnd *frmWnd = dynamic_cast<CFrameWnd *> (mainWnd);
assert(frmWnd);
m_pDoc = dynamic_cast<CUserInterfaceDoc *> (frmWnd);
assert(m_pDoc);
...你只是错过了C-Style演员阵容中的GetActiveDocument()调用。所以它应该像这样工作:
CUserInterfaceDoc *m_pDoc;
CWnd * mainWnd = AfxGetMainWnd();
assert(mainWnd);
CFrameWnd *frmWnd = dynamic_cast<CFrameWnd *> (mainWnd);
assert(frmWnd);
m_pDoc = dynamic_cast<CUserInterfaceDoc *> (frmWnd->GetActiveDocument());
assert(m_pDoc);
DYNAMIC_DOWNCAST是soo oldschool,如果启用RTTI(默认情况下处于启用状态),实际上不再需要它。 另见:MFC DYNAMIC_DOWNCAST vs. dynamic_cast