加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 使用unique_ptr的联合

发布时间:2020-12-16 05:50:03 所属栏目:百科 来源:网络整理
导读:尝试在工会中使用unique_ptr时,当我尝试std :: move或std :: make_unique时,会给我一个segfault. #include iostream#include memoryunion myUnion{ struct{std::unique_ptrfloat upFloat;}structUpFloat; struct{std::unique_ptrint upInt;}structUpInt; myU
尝试在工会中使用unique_ptr时,当我尝试std :: move或std :: make_unique时,会给我一个segfault.
#include <iostream>
#include <memory>

union myUnion{
    struct{std::unique_ptr<float> upFloat;}structUpFloat;
    struct{std::unique_ptr<int> upInt;}structUpInt;
    myUnion(){}
    ~myUnion(){}
};
struct myStruct{
    int x;
    myUnion num;

};
int main()
{
    myStruct aStruct,bStruct;
    aStruct.x = 1;
    bStruct.x = 2;

    auto upF = std::make_unique<float>(3.14);
    auto upI = std::make_unique<int>(3);

    aStruct.num.structUpFloat.upFloat = std::move(upF);
    bStruct.num.structUpInt.upInt = std::move(upI);

    std::cout << "aStruct float = " << *aStruct.num.structUpFloat.upFloat << std::endl;
    std::cout << "bStruct int = " << *bStruct.num.structUpInt.upInt << std::endl;
    return 0;
}

但是,使用正常指针可以按预期方式工作:

#include <iostream>
#include <memory>

union myUnion{
    struct{float *pFloat;}structPFloat;
    struct{int *pInt;}structPInt;
    myUnion(){}
    ~myUnion(){}
};
struct myStruct{
    int x;
    myUnion num;

};
int main()
{
    myStruct aStruct,bStruct;
    aStruct.x = 1;
    bStruct.x = 2;

    auto upF = std::make_unique<float>(3.14);
    auto upI = std::make_unique<int>(3);

    aStruct.num.structPFloat.pFloat = upF.get();
    bStruct.num.structPInt.pInt = upI.get();

    std::cout << "aStruct float = " << *aStruct.num.structPFloat.pFloat << std::endl;
    std::cout << "bStruct int = " << *bStruct.num.structPInt.pInt << std::endl;
    return 0;
}

这是使用clang.3.4.2或gcc.4.9.0.所以我假设我在这里做错了.任何帮助将不胜感激.

编辑:

好的,所以分享我定下的代码可能是一件好事.非常感谢所有指出我使用新版本管理变体成员中我的指针的生命的人.

#include <memory>
#include <iostream>
#include <vector>
struct myStruct
{
public:
    union
    {
        std::unique_ptr<float> upFloat;
        std::unique_ptr<int> upInt;
    };
    enum class unionType {f,i,none} type = unionType::none; // Keep it sane
    myStruct(){}
    myStruct(std::unique_ptr<float> p)
    {
        new (&upFloat) std::unique_ptr<float>{std::move(p)};
        type = unionType::f;
    }
    myStruct(std::unique_ptr<int> p)
    {
        new (&upInt) std::unique_ptr<int>{std::move(p)};
        type = unionType::i;
    }
    ~myStruct()
    {
        switch (type)
        {
            case unionType::f: upFloat.~unique_ptr<float>(); break;
            case unionType::i: upInt.~unique_ptr<int>(); break;
        }
    }
};

int main()
{
    std::vector<std::unique_ptr<myStruct>> structVec;
    structVec.push_back(std::make_unique<myStruct>(std::make_unique<float>(3.14f)));
    structVec.push_back(std::make_unique<myStruct>(std::make_unique<int>(739)));
    structVec.push_back(std::make_unique<myStruct>());
    structVec.push_back(std::make_unique<myStruct>(std::make_unique<float>(8.95f)));
    structVec.push_back(std::make_unique<myStruct>(std::make_unique<int>(3)));
    structVec.push_back(std::make_unique<myStruct>());

    for(auto &a: structVec)
    {
        if(a->type == myStruct::unionType::none)
        {
            std::cout << "Struct Has Unallocated Union" << std::endl;
        }
        else if(a->type == myStruct::unionType::f)
        {
            std::cout << "Struct float = " << *a->upFloat << std::endl;
        }
        else
        {
            std::cout << "Struct int = " << *a->upInt << std::endl;
        }
        std::cout << std::endl;
    }

    return 0;
}

输出:

Struct float = 3.14

Struct int = 739

结构有未分配联盟

Struct float = 8.95

Struct int = 3

结构有未分配联盟

解决方法

对于无限制的联盟,你必须管理自己一些构造/破坏.

以下可能有帮助:

union myUnion{
    std::unique_ptr<float> upFloat;
    std::unique_ptr<int> upInt;

    myUnion(){ new (&upFloat) std::unique_ptr<float>{};}
    ~myUnion() {}
};

class myStruct
{
public:
    ~myStruct()
    {
        destroy();
    }

    void destroy()
    {
        switch (type)
        {
            case unionType::f: num.upFloat.~unique_ptr<float>(); break;
            case unionType::i: num.upInt.~unique_ptr<int>(); break;
        }
    }

    void set(std::unique_ptr<int> p)
    {
        destroy();
        new (&num.upInt) std::unique_ptr<int>{std::move(p)};
        type = unionType::i;
    }
    void set(std::unique_ptr<float> p)
    {
        destroy();
        new (&num.upFloat) std::unique_ptr<float>{std::move(p)};
        type = unionType::f;
    }

public:
    enum class unionType {f,i} type = unionType::f; // match the default constructor of enum
    myUnion num;
};

int main()
{
    myStruct aStruct,bStruct;

    aStruct.set(std::make_unique<float>(3.14f));
    bStruct.set(std::make_unique<int>(3));

    std::cout << "aStruct float = " << *aStruct.num.upFloat << std::endl;
    std::cout << "bStruct int = " << *bStruct.num.upInt << std::endl;
    return 0;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读