静态检查工具显示了对以下代码的违反:
class CSplitFrame : public CFrameWnd
...
class CVsApp : public CWinApp
CWnd* CVsApp::GetSheetView(LPCSTR WindowText)
{
CWnd* pWnd = reinterpret_cast<CSplitFrame*>(m_pMainWnd)->m_OutputBar.GetChildWnd(WindowText);
return pWnd;
}错误消息:类'CSplitFrame‘继承了类'CWnd’
描述:避免转换继承层次结构。此规则检测基类指针到子类指针的转换。
的好处:允许转换继承层次结构的会导致维护问题,而从基类降级总是非法的。
参考文献:
您认为不将基类指针转换为子类指针是一个很好的实践吗?我为什么和什么时候应该遵循这个规则?
发布于 2010-10-06 02:53:04
让我们看一下MFC中的一些下拉式示例:
CButton*来自CWnd*
CWnd* wnd = GetDlgItem(IDC_BUTTON_ID);
CButton* btn = dynamic_cast<CButton*>(wnd);CChildWnd*来自CFrameWnd*
CChildWnd * pChild = ((CSplitFrame*)(AfxGetApp()->m_pMainWnd))->GetActive();MFC设计确实存在一定的局限性。
由于CWnd提供了MFC中所有窗口类的基本功能,它甚至充当视图、对话框、按钮等的基类。
如果我们想避免降级,我们可能需要MFC黑客将CWnd分解成更少的碎片?
现在,谈到另一个问题,如何解决违规行为,我的看法是尽量避免不安全的下线,通过使用安全下线:
Parent *pParent = new Parent;
Parent *pChild = new Child;
Child *p1 = static_cast<Child*>(pParent); // Unsafe downcasting:it assigns the address of a base-class object (Parent) to a derived class (Child) pointer
Parent *p2 = static_cast<Child*>(pChild); // Safe downcasting:it assigns the address of a derived-class object to a base-class pointer这是使用安全下线的良好做法,即使违法行为仍然存在,我们也会用解释来压制。
很少有有用的参考资料:
http://support.microsoft.com/kb/108587
http://blog.csdn.net/ecai/archive/2004/06/26/27458.aspx
http://www.codeproject.com/KB/mcpp/castingbasics.aspx
downcasting.html
最后,感谢大家的各种有益回应。
它们确实很有帮助。
发布于 2010-09-30 16:00:58
reinterpret_cast在这里肯定是个坏主意,不管编码标准还是OOP理论。它必须是dynamic_cast或下浇。
至于有效C++的第39章,它集中讨论了由于必须降到多个不同类型并必须检查dynamic_cast的返回值以确定潜在故障而导致的维护问题,从而导致代码中的多个分支:
重要的是:如果-然后-如果-然后-其他风格的编程不可避免地导致是远远低于使用虚拟函数,你应该保留它的情况下,你真的没有其他选择。
发布于 2010-10-03 22:44:53
在我看来,这并不是真的有必要让你去表演演员表演,或者至少不是你正在做的那样。您的函数需要返回一个CWnd,因此不需要转换到CSplitFrame。
我本以为GetChildWnd会返回一个CWnd*或类似的内容;为什么您不能写这样的东西:
CWnd* CVsApp::GetSheetView(LPCSTR WindowText)
{
return m_pMainWnd->m_OutputBar.GetChildWnd(WindowText);
}https://stackoverflow.com/questions/3832420
复制相似问题