为啥我可以毫无错误地转换不相关类的指针?

Posted

技术标签:

【中文标题】为啥我可以毫无错误地转换不相关类的指针?【英文标题】:Why can I cast pointers of unrelated classes without error?为什么我可以毫无错误地转换不相关类的指针? 【发布时间】:2014-07-14 18:40:40 【问题描述】:

我一直在试验指针,写了如下代码:

#include <iostream>

using std::cout;

struct A

    int a;
    char b;
    A() a = 4; 
;

struct B

    int c;
    B() c = 5; 
;

A *a = new A;
B *b = new B;

int main()
 
    a = (A*)b; 
    cout << a -> a; //5

为什么B*可以转换成A*?任何指针都可以转换成其他指针吗?

【问题讨论】:

即使你的编译器什么也没说(因为显式转换意味着“我知道潜在的问题,不要警告我”),你在做什么也是完全错误的。它给出了预期的结果是巧合(因为 a 和 c 具有相同的字节偏移并且在 A 和 B 中键入) 任何类型的指针都可以转换为任何其他类型是不完全正确的。但它可以转换为比应有的类型更多的类型。 @Beta 你能提供合适的例子吗? 该语言允许您将指向任何事物的指针转换为指向(大部分)其他事物的指针。除非在少数有限的情况下,否则无法安全地使用结果。 c-style cast (A*) 是一把大锤。使用static_cast&lt;A*&gt; 让编译器检查您的类型是否相关。 @mark-b 也许这被关闭得太快了:-/ ... 【参考方案1】:

“任何指针都可以转换成其他指针吗?”

如果你使用这样的 c 风格转换,是的。

a = (A*)b; 

b 指向的结构将被(重新)解释,就像 A 一样。正确的 c++ 等价物是

a = reinterpret_cast<A*>(b);

您从此类演员阵容中通过一致性获得的体验不太可能符合预期。 换句话说:您将体验到各种未定义的行为,在进行此类转换后访问a 的任何成员。


应该使用static_cast&lt;&gt; 让编译器检查这些类型是否相关,以及是否可以以某种方式合理地进行转换

a = static_cast<A*>(b); 

查看这些在线示例,了解static_cast&lt;&gt;reinterpret_cast&lt;&gt; 的区别。

【讨论】:

以上是关于为啥我可以毫无错误地转换不相关类的指针?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我会收到“从 '[String]' 转换为不相关的类型 'String' 总是失败”错误?

为啥在 C++ 中一个类的指针可以转换为另一个类的指针?

为啥我不能使用子类的指针访问基类的公共函数?

我找不到我的链表的错误(为啥我的头指针在移动?)

多重签名钱包未转换。为啥聚合交易不返回错误?

为啥我会收到此错误? “孩子未申报?