内存中的 C++ 联合

C++ Unions in the Memory

我正在摆弄如下代码:

union Data { 
    int i;
    double x;
    std::string str;
    ~Data(){}
};

union Data var = {.x = 31293.932};

std::cout << var.x << "\n";
std::cout << var.str << "\n";
std::cout << var.i << "\n";

据我所知,在我将 x 成员设置为某个浮点数后,联合体有一些 64 位的东西。然后我想查看相应的字符串,假设我将这些字节视为 char。但是当我尝试将其打印为字符串时出现分段错误。这是为什么?我初始化了联合,所以我假设 var.str 也必须初始化。

str未构造。如果必须使用 str,则必须为其提供构造函数或通过 placement new 构造它。下面是一个完整的例子

#include <iostream>
#include <vector>

using namespace std;

union Data
{
    int i;
    double x;
    std::string str;
    Data() {}
    Data(std::string st) : str(st) {}
    ~Data() {}
};

int main()
{
    Data var;
    var.x = 31293.932;
    new (&var.str) std::string("Hello World!");


    std::cout << var.x << "\n";
    std::cout << var.str << "\n";
    std::cout << var.i << "\n";

//destroy it
    var.str.std::string::~string();
}

编辑:

稍微扩展一下我的回答...

MSDN 似乎比 cppreference 对联合有更友好的解释。所以,检查:Unions - MSDN and Unions - cppreference

您应该使用 char 来访问联合中的字节。 std::string 不是 POD 类型,不能以这种方式使用。

试试这个:

union Data { 
    int i;
    double x;
    char bytes[sizeof(double)];
    ~Data(){}
};

union Data var = {.x = 31293.932};

std::cout << var.x << "\n";
std::cout.write(var.bytes, sizeof(var.bytes));
std::cout << "\n" << var.i << "\n";

什么是广泛的 POD 类型的完整定义。用非常简单的术语来说,它是一种没有显式定义的复制构造函数、析构函数或虚方法的基本数据类型,如果它是聚合类型(如结构、class 和联合),则它本身不包含任何此类类型.