C 风格强制转换和 C++ static_cast 到指针引用

mil*_*sma 6 c++ mfc casting

这不是 C++11

我对 Microsoft 的CMapStringToOb::GetNextAssoc的第三个参数感兴趣 ,它具有以下定义:

 void GetNextAssoc(
   POSITION& rNextPosition,
   CString& rKey,
   CObject*& rValue 
) const;
Run Code Online (Sandbox Code Playgroud)

然后我得到了以下简单的测试代码:两个好的案例和一个有编译器错误的案例。

class CMyObject : public CObject    //in order to use CMapStringToOb
{
public:
    CMyObject(CString name_)
        :name(name_)
    {
    }

    void SayHello()
    {
        TRACE(_T("hello") + name);
    }
    CString name;   
};

void main()
{
    CMapStringToOb myMap;
    myMap.SetAt(_T("a"), new CMyObject(_T("aaa")));
    myMap.SetAt(_T("b"), new CMyObject(_T("bbb")));
    myMap.SetAt(_T("c"), new CMyObject(_T("ccc")));

    //good case 1
    POSITION pos = myMap.GetStartPosition();
    while (pos)
    {
        CString s;
        CMyObject* pMine = NULL;
        myMap.GetNextAssoc(pos, s, (CObject*&)pMine);
        if(pMine)
        {
            pMine->SayHello();
        }
    }

    //good case 2
    pos = myMap.GetStartPosition();
    while (pos)
    {
        CString s;
        CObject* pObject = NULL;
        myMap.GetNextAssoc(pos, s, pObject);
        if(pObject)
        {
            CMyObject* pMine = static_cast<CMyObject*>(pObject);
            pMine->SayHello();
        }
    }

    //bad case:
    //can not compile
    //    error C2440: 'static_cast' : cannot convert from 'CMyObject *' to 'CObject *&'    
    //        static_cast and safe_cast to reference can only be used for valid initializations or for lvalue casts between related classes 

    pos = myMap.GetStartPosition();
    while (pos)
    {
        CString s;
        CMyObject* pMine = NULL;
        myMap.GetNextAssoc(pos, s, static_cast<CObject*&>(pMine));  //compile error
        if(pMine)
        {
            pMine->SayHello();
        }
    }   
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我想做的就是找到一种正确的方法将 C 样式转换替换为 C++ 样式转换。

读到这里,它提到:

C 类型转换是使用 (type)object 或 type(object) 进行类型转换。C 风格转换被定义为以下第一个成功的转换:

const_cast
static_cast (though ignoring access restrictions)
static_cast (see above), then const_cast
reinterpret_cast
reinterpret_cast, then const_cast
Run Code Online (Sandbox Code Playgroud)

Q1:上面的列表是否缺少任何内容(例如 rValue)?

Q2:在这种情况下,将 C 风格转换为 C++ 风格转换的正确方法是什么?(案例 2 很好,但是,还有更简洁的吗?)

问题 3:rValue 的 C 风格转换效果如何?(换句话说,请解释为什么好的案例1有效)

Joh*_*nck 3

您不能static_cast在“不相关类型”的引用(或指针)之间。虽然您可以static_cast从 aCMyObject*到 a CObject*,但这不是您在这里所做的。在这里,您尝试将对指针的引用转换为对另一个指针的引用。并且这两种指针类型不存在继承关系。

我喜欢你的“good case 2”代码——我会用它来运行。

有关指针类型的非相关性的更多详细信息,请参阅此处:static_cast 和对指针的引用