【问题标题】: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_castdynamic_cast 看看会发生什么。
  • 但是你没有使用 C++,那些是 C 风格的转换。 C++有static_castdynamic_castreinterpret_cast等类型转换操作符。
  • The C++ compiler should not allow valid C syntax wat。 FWIW,您始终可以使用 -Wold-style-cast 进行编译
  • @Surfing_SO 有很多事情会导致未定义的行为,但不需要编译器给出错误。事情就是这样。部分原因是历史原因,但很多时候是出于实际原因。语言工具的存在是为了帮助您避免导致未定义的行为,在这种情况下是 C++ 风格的强制转换。但是如果你下定决心要朝自己的脚开枪,C++ 不提供铠甲靴。
  • 如果 C++ 编译器不编译 C 风格的强制转换,就无法再使用 C++ 编译器编译 C 代码,并且 C++ 将失去其主要功能之一(而且他们将拥有将其重命名为其他名称;))

标签: c++ pointers casting


【解决方案1】:

C cast 语法会根据所涉及的类型做不同的事情。它可以做的事情之一是reinterpret_cast

这是您不应该使用 C 强制转换语法而坚持使用 C++ 强制转换的原因之一。使用 C++ 强制转换,您可以获得您要求的操作,而不是可能的其他操作。

c++ 编译器不应该允许这样做,并且应该抛出编译时错误。

C 兼容性是 C++ 成功的原因之一。 C 不应该有这种“多态”强制转换语法,但它确实有,而且 C++ 需要兼容。如果您正在编写新的 C++ 代码,则根本不应该使用旧语法。

在某些编译器上,您可以使用以下内容禁用 C 样式转换:-Werror=old-style-cast

【讨论】:

    【解决方案2】:

    您展示的示例被称为“不安全”或“未经检查”的演员表,这是完全正确的。它是从向后兼容 C 继承而来的低级结构。您不应该在现代 C++ 代码中使用它。

    进行强制转换的正确方法是使用操作static_castdynamic_cast 或其亲属。详情请参阅相关问题When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?

    您可以通过使用选项-Wold-style-cast 强制 GCC 为这些类型转换显示警告。要将所有警告转换为错误,可以添加选项-Werror

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-08
      • 2021-09-20
      • 2015-06-19
      • 2011-04-15
      • 1970-01-01
      • 2021-04-07
      • 1970-01-01
      相关资源
      最近更新 更多