程序在可区分联合的复制构造函数内崩溃

Program crashes inside the copy constructor of a discriminated union

所以我一直在尝试为我的项目创建一个受歧视的联盟。来自 C,我认为这将是微不足道的......;)

结构命名为Message。它有一个 MessageType 和一个包含 MessageGetMessageSet 的内部联合。

enum MessageType {
    MESSAGE_GET,
    MESSAGE_SET
};

struct MessageGet {
    std::string store_name;
    std::vector<uint8_t> key;
};

struct MessageSet {
    std::string store_name;
    std::vector<uint8_t> key;
    std::vector<uint8_t> value;
};

struct Message {
    MessageType type;

    uint64_t sender_id;    

    union U {
        U() : get() {}

        U(const U& other) {
            get = other.get;
            set = other.set;
        }

        ~U() {}

        U& operator=(const U& other) {
            set = other.set;
            get = other.get;
            return *this;
        }

        MessageGet get;

        MessageSet set;
    } as;

    Message() {}

    ~Message() {
        switch (type) {
            case MESSAGE_GET: {
                as.get.~MessageGet();
                break;
            }
            case MESSAGE_SET: {
                as.set.~MessageSet();
                break;
            }
        }
    }

    Message(MessageGet get, uint64_t sender_id) {
        type = MESSAGE_GET;
        as.get = get;
        sender_id = sender_id;
    }

    Message(MessageSet set, uint64_t sender_id) {
        type = MESSAGE_SET;
        as.set = set;
        sender_id = sender_id;
    }

    Message(const Message& other) {
        type = other.type;
        as = other.as;
        sender_id = other.sender_id;
    }

    Message& operator=(const Message& other) {
        type = other.type;
        as = other.as;
        sender_id = other.sender_id;
        return *this;
    }
};

程序在我执行类似操作的代码中的其他地方崩溃:

Message message(MessageGet {std::move(store_name), std::move(key)}, sender);
messages.push_back(message); // messages is a local std::vector<Message>

它不会异常崩溃 - 只是崩溃。

我设法将其缩小到 Message 复制构造函数内部。在那之后,不知道是什么原因造成的。将不胜感激。

    U(const U& other) {
        get = other.get;
        set = other.set;
    }

这总是最后设置 set,使 get 的值无效。当您设置一个联合成员时,它会使所有其他成员无效。这就是联合与结构的不同之处。

你在哪里:

    as = other.as;

您必须将其更改为仅复制有效成员。