内存中的C ++联盟

时间:2016-02-11 19:23:22

标签: c++ unions

我正在摆弄以下代码:

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。但是当我尝试将其打印为字符串时,我遇到了分段错误。这是为什么?我初始化了union,所以我假设var.str也必须初始化。

2 个答案:

答案 0 :(得分:4)

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 - MSDNUnions - cppreference

答案 1 :(得分:0)

您应该使用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类型广泛的完整定义。简单来说,它是没有显式定义的复制构造函数,析构函数或虚方法的基本数据类型,如果它是聚合类型(如struct,class和unions),它本身不包含任何此类类型。