为啥在 C++ 中一个类的指针可以转换为另一个类的指针?
Posted
技术标签:
【中文标题】为啥在 C++ 中一个类的指针可以转换为另一个类的指针?【英文标题】:Why in C++ a pointer of one class can be casted to a pointer of another class?为什么在 C++ 中一个类的指针可以转换为另一个类的指针? 【发布时间】:2014-07-04 05:01:38 【问题描述】:class A
public:
void display()
cout << "class A\n";
;
class B
public:
void show()
cout << "class B\n";
;
int main()
A* aPtr = new A;
B* bPtr = new B;
B* bPtr2 = (B*) aPtr;
return 0;
在上面的代码中,为什么在 C++ 中允许将一个类类型的指针转换为另一个类类型。由于这两个类仍然不相关,为什么B* bPtr2 = (B*) aPtr;
不会抛出编译时错误来转换不相关类型的指针。
【问题讨论】:
这是一个 C 风格的转换,编译器假定你知道你在做什么......尝试static_cast
或dynamic_cast
看看会发生什么。
但是你没有使用 C++,那些是 C 风格的转换。 C++有static_cast
、dynamic_cast
、reinterpret_cast
等类型转换操作符。
The C++ compiler should not allow valid C syntax
wat。 FWIW,您始终可以使用 -Wold-style-cast
进行编译
@Surfing_SO 有很多事情会导致未定义的行为,但不需要编译器给出错误。事情就是这样。部分原因是历史原因,但很多时候是出于实际原因。语言工具的存在是为了帮助您避免导致未定义的行为,在这种情况下是 C++ 风格的强制转换。但是如果你下定决心要朝自己的脚开枪,C++ 不提供铠甲靴。
如果 C++ 编译器不编译 C 风格的强制转换,就无法再使用 C++ 编译器编译 C 代码,并且 C++ 将失去其主要功能之一(而且他们将拥有将其重命名为其他名称;))
【参考方案1】:
C cast 语法会根据所涉及的类型做不同的事情。它可以做的事情之一是reinterpret_cast
。
这是您不应该使用 C 强制转换语法而坚持使用 C++ 强制转换的原因之一。使用 C++ 强制转换,您可以获得您要求的操作,而不是可能的其他操作。
c++ 编译器不应该允许这样做,并且应该抛出编译时错误。
C 兼容性是 C++ 成功的原因之一。 C 不应该有这种“多态”强制转换语法,但它确实有,而且 C++ 需要兼容。如果您正在编写新的 C++ 代码,则根本不应该使用旧语法。
在某些编译器上,您可以使用以下内容禁用 C 样式转换:-Werror=old-style-cast
。
【讨论】:
【参考方案2】:您展示的示例被称为“不安全”或“未经检查”的演员表,这是完全正确的。它是从向后兼容 C 继承而来的低级结构。您不应该在现代 C++ 代码中使用它。
进行强制转换的正确方法是使用操作static_cast
、dynamic_cast
或其亲属。详情请参阅相关问题When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?。
您可以通过使用选项-Wold-style-cast
强制 GCC 为这些类型转换显示警告。要将所有警告转换为错误,可以添加选项-Werror
。
【讨论】:
以上是关于为啥在 C++ 中一个类的指针可以转换为另一个类的指针?的主要内容,如果未能解决你的问题,请参考以下文章