2016-09-21 42 views
-7

我总是读到C++中的C风格转换与reinterpret_cast相同。但是,我只是在Visual Studio中测试了这段代码,看起来C风格的转型与静态转型执行的行为相同。有人知道为什么吗?这似乎是一个错误......在C++中使用C风格铸造怪异行为

#include <string> 
#include <iostream> 

class Thing1 
{ 
    std::string theString; 

public: 
    Thing1(const std::string& theString) : theString(theString) 
    { 
     // 
    } 

    std::string getTheString() 
    { 
     return theString; 
    } 
}; 

class Thing2 
{ 
    std::string theString; 

public: 
    Thing2(const std::string& theString) : theString(theString) 
    { 
     // 
    } 

    std::string getTheString() 
    { 
     return theString; 
    } 
}; 

class Thing3 : public Thing1, public Thing2 
{ 
public: 
    Thing3(const std::string& theString1, const std::string& theString2) : Thing1(theString1), Thing2(theString2) 
    { 
     // 
    } 
}; 

int main() 
{ 
    Thing3* thing3 = new Thing3("string1", "string2"); 
    uintptr_t t3ptr = (uintptr_t)thing3; 
    uintptr_t t1ptr = (uintptr_t)((Thing1*)thing3); 
    uintptr_t t2ptr = (uintptr_t)((Thing2*)thing3); 
    std::cout << t1ptr << std::endl; 
    std::cout << t2ptr << std::endl; 
    std::cout << t3ptr << std::endl; 
    std::cin.ignore(); 
    return 0; 
} 

这段代码给出了输出:

17563752 
17563780 
17563752 
+0

C风格的演员阵容不一定与reinterpret_cast相同。在C++中,C风格强制转换只会等同于reinterpret_cast或const_cast(如果static_cast不行)。我希望我不要过分简化事情,但我相信这是事情的要点。 – antred

+6

*“我总是读C++中的C风格类型与reinterpret_cast相同。”* - 要么你没有记错,要么你对阅读材料的选择特别不走运。 – IInspectable

+1

倾向于使用C++强制转换* always *。他们更明确地说出你想要做什么*和*他们更容易在源代码中搜索。当然,*最好的*是设计代码,所以不需要(或者很少)演员。 –

回答

7

C风格的转换是不一样的reinterpret_cast。

铸造的概要可以在这里找到: http://en.cppreference.com/w/cpp/language/explicit_cast

以下顺序:

一个)的const_cast(表达); b)static_cast(表达式),带有扩展:对派生类的指针或引用还允许被转换为指针或引用明确的基类(反之亦然),即使基类不可访问(即,此转换忽略私有继承说明符)。同样适用于将指向成员的指针指向非明确的非虚拟基的成员;

c)static_cast(带扩展名)后跟const_cast;

d)reinterpret_cast(expression);

e)reinterpret_cast后跟const_cast。

+0

谁决定了这种行为? dumb as hell – Finke

+2

@Finke:很明显,这个命令是由标准委员会制定的。该命令在[cast.expr]第4节中列出。C还描述了类型转换的强制转换行为。 – jxh

+6

@Finke:认为编译器有错误的人是因为他们无法阅读任何文档。这种行为总比'reinterpret_cast'ing好得多,并且更接近于C的工作方式。像'(int)5.5'这样的东西如果C风格演员只是'reinterpret_cast'的简称,并且假设'reinterpret_cast'只是根据需要按位进行类型化处理,那么结果是表情在几乎所有的时间都是毫无用处的。 – GManNickG