c++ - 将结构指针转换为 C++ 中的 union 指针

标签 c++ casting

我有一个包含各种结构成员的 union 体。

union U {
    struct S1 as_s1;
    struct S2 as_s2;
    …
};

如何在 C++ 中将指向 struct as_s1 的指针转换为指向 union U 的指针?

我知道是因为this它可以很容易地使用 C 转换来完成。但是我想使用 C++ 的 Advance class type casting 特性而不会导致任何错误。

最佳答案

来自标准 6.9.2.4。

Two objects a and b are pointer-interconvertible if:

  1. they are the same object, or
  2. one is a standard-layout union object and the other is a non-static data member of that object (12.3),
  3. one is a standard-layout class object and the other is the first non-static data member of that object, or, if the object has no non-static data members, the first base class subobject of that object (12.2), or
  4. there exists an object c such that a and c are pointer-interconvertible, and c and b are pointer-interconvertible.

If two objects are pointer-interconvertible, then they have the same address, and it is possible to obtain a pointer to one from a pointer to the other via a reinterpret_cast (8.2.10).

这意味着您可以使用 reinterpret_cast 将它们相互转换。但是,您不能访问错误类型的内存。例如,下面是一个定义良好的代码:

#include <iostream>

struct S1 {
  int i;
};

struct S2 {
  short int i;
};

union U {
  struct S1 as_s1;
  struct S2 as_s2;
};

void printUnion(U* u, int type) {
  if (type == 0){
    S1 *s1 = reinterpret_cast<S1*>(u);
    std::cout << s1->i << std::endl;
  } else {
    S2 *s2 = reinterpret_cast<S2*>(u);
    std::cout << s2->i << std::endl;
  }
}

int main() {
  S1 s1{1};
  printData(reinterpret_cast<U*>(&s1), 0);
  S2 s2{2};
  printData(reinterpret_cast<U*>(&s2), 1);
}

但是,如果您为 printData 函数提供了错误的类型参数,则行为是未定义的。

在 c++ 中,很难想象一个设计良好的程序会需要强制转换。在 c 中,如果您已经需要一个 union 对象,则可能会出现这种情况,可以使用它来实现多态性(当然那里没有 reinterpret_cast)。尽管通常使用 void* 来完成。

关于c++ - 将结构指针转换为 C++ 中的 union 指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49491939/

相关文章:

c++ - 以这种方式使用 boost::asio::strand 是否安全?

SQL错误 "ORA-01722: invalid number"

C# 分配/强制转换为结构中的对象字段

c - 检测从 void * 到错误指针类型的转换

Typescript - 如何禁止两种解析为相同类型的类型别名互换使用?

c++ - std::regex 的正则表达式选项

c++ - 在单独的类上设置 WinEvent

c++ - Lua 校验数据类型 C++

c++ - 连接期间的mysql c++段错误

c++ - static_cast 整数到枚举的转换