【问题标题】:A conversion that C-style cast can handle, but C++ casts cannotC 样式转换可以处理,但 C++ 转换不能处理的转换
【发布时间】:2015-11-25 04:04:30
【问题描述】:

It is said C 风格的转换只是尝试应用不同的 C++ 转换组合,并使用第一个允许的组合。但是,我有一种感觉,我听说有些情况只有 C 风格的转换可以处理,而 C++ 转换的组合是不允许的。

我错了吗?在 any 上下文(在 C++ 中)中的 any C 样式转换是否可以用 C++ 转换的适当组合替换?

UPD感谢Cheers and hth. - Alf,我们有了一个C++ 强制转换无法处理的示例,这意味着它们无法产生已定义预期 行为.高级问题是提供一个 C++ 强制转换无法处理的示例,这意味着它甚至无法编译

【问题讨论】:

  • “我有一种感觉,我听说有些情况只有 C-style cast 可以处理,而不允许任何 C++ casts 的组合”——我怀疑你听到的是C 允许一些 C++ 不允许的类型转换。就 C++ 类型转换而言,这与 C 风格类型转换的 含义 无关。然而,我没有一个方便的例子。
  • @JohnBollinger,您仍然可以通过组合 C++ 样式转换来执行相同的转换。
  • 不是一直都有reinterpret_cast吗?
  • @CompuChip 不,reinterpret_cast 甚至不能做一些事情 static_cast 可以,而两者都与 const_cast 正交。

标签: c++ c casting


【解决方案1】:

强制转换为不可访问的基数只能表示为 C 样式强制转换(语法变体之一)。在这种情况下,它等效于static_cast,它可能会更改地址,但static_cast 无法访问基址。

例子:

struct Base
{
    int x = 42;
};

struct Oh_my
    : private Base
{
    virtual ~Oh_my() {}
};

#include <iostream>
using namespace std;
auto main() -> int
{
    Oh_my o;
    cout << "C cast: " << ((Base&)o).x << endl;
    cout << "reinterpret_cast: " << reinterpret_cast<Base&>(o).x << endl;
}

在 Windows 7 中使用 MingW g++ 输出:

C演员:42 reinterpret_cast: 4935184

但由于它是相当未定义的行为,所以最后一个输出操作可能会崩溃。

【讨论】:

  • @MooingDuck struct A { int i; }; struct B { int i; }; struct C : private A, private B { };,然后进行从C *A *B * 的C 样式转换将起作用,而static_cast 将失败,reinterpret_cast至少其中一个会给出错误的结果。
  • @hvd:对,我就是这么想的。 reinterpret_cast 可以工作,但它需要指针算术和编译器内部知识,所以我认为这是“C++ casts can't handle”。
  • 虚拟析构函数的目的是什么?如果我删除它,我会得到两个演员相同的输出。
  • 这与@hvd 的多重继承相同,以实际上确保(或至少一个)基本子对象与最派生的地址不同对象。
  • @Mikhail: 很确定reinterpret_cast编译 C 将转换的任何东西,假设每个类型都相同。
猜你喜欢
  • 2016-01-30
  • 2014-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-22
  • 2018-08-10
  • 2012-05-06
  • 2019-07-12
相关资源
最近更新 更多