代码之家  ›  专栏  ›  技术社区  ›  wengseng

关于从基类向下转换到子类指针

  •  5
  • wengseng  · 技术社区  · 15 年前

    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;
    }
    

    错误消息:

    说明: 避免向下转换继承层次结构。

    好处: 允许向下转换继承层次结构会导致维护问题,而从基类向下转换总是非法的。

    参考文献:

    1. 联合攻击战斗机、飞行器、C++编码标准第4.23类转换、AV规则178

    您认为不从基类指针向下转换到子类指针是一个好的实践吗?我为什么和什么时候应该遵守这个规则?

    4 回复  |  直到 8 年前
        1
  •  10
  •   Cubbi    15 年前

    reinterpret_cast dynamic_cast boost::polymorphic_downcast .

    至于有效C++第39章,它集中于由于不得不向下压到多个不同类型并检查返回值而导致的维护问题。 动态播放 对于导致代码中出现多个分支的潜在故障:

        2
  •  4
  •   wengseng    15 年前

    让我们看一下MFC中的一些向下投射示例:

    C按钮*来自CWnd*

    CWnd* wnd = GetDlgItem(IDC_BUTTON_ID);
    CButton* btn = dynamic_cast<CButton*>(wnd);
    

    CChildWnd * pChild = ((CSplitFrame*)(AfxGetApp()->m_pMainWnd))->GetActive();
    

    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
    http://www.bogotobogo.com/cplusplus/upcasting_downcasting.html

    最后,感谢各位的各种有益回应。
    他们确实很有帮助。

        3
  •  0
  •   Peter    15 年前

    在我看来,不管怎么说,你都没有必要表演这个角色,或者至少在你表演的时候没有必要。函数需要返回 CWnd ,所以你不需要向 CSplitFrame .

    GetChildWnd CWnd* 或者类似的;为什么你不能写这样的东西:

    CWnd* CVsApp::GetSheetView(LPCSTR WindowText)
    {
       return m_pMainWnd->m_OutputBar.GetChildWnd(WindowText);
    }
    
        4
  •  0
  •   AnT stands with Russia    15 年前

    在正确设计的OOP代码中,向下转换类指针通常是应该不惜一切代价避免的。然而,有时这样的强制转换是必要的,特别是如果您正在使用一些其他库/代码,而这些库/代码是为在客户机代码中需要这样的强制转换而设计的。MFC就是这种库的一个例子。

    当确实有必要进行降级时,不应使用 reinterpret_cast . 正确的表演方式是 dynamic_cast static_cast .

    重新解释 重新解释 静态浇铸 ,但是 动态播放 静态浇铸

    推荐文章