如何与非平凡的成员这样的工会像班级一样正常工作

How to make union like class with non-trivial member work properly?

本文关键字:一样 工作 常工作 成员      更新时间:2023-10-16

我在试图与具有非平凡驱动器工作的成员进行类似工会的类别时面临两个问题。我无法理解的细分故障,也是一种有条件地调用非平凡驱动器的方法。

#include <iostream>
#include <string>
using namespace std;
class A {
    struct B {
        int u;
        double v;
        string w;
    };
    union C {
        B x;
        unsigned char y;
        C(int u, double v, const string& w) {
            x.w = w;// why does it segfault here?
            x.u = u;
            x.v = v;
        }
        C(unsigned char c) {
            y = c;
        }
        //omitting this complains because string has non-trivial destructor
        ~C() {
            // how to call this conditionally based on A::isChar value
            //x.w.~string();
        }
    } c;
    bool isChar;
public:
    A(unsigned char f)
    : isChar{true}, c(f) {}
    A(int g, double h, const string& i)
    : isChar{false}, c(g, h, i) {}
    friend ostream& operator<<(ostream& os, const A& a) {
        if(a.isChar)
            return os << a.c.y;
        return os << a.c.x.u << " " << a.c.x.v << " " << a.c.x.w;
    }
};
int main() {
    A a1(10, 20.0, "samik"), a2('v');
    cout << a1 << " " << a2 << endl;
    return 0;
}

我将使用g++ -g -std=c++14 -pedantic union_class_test.cpp -o union_class_test.out与GCC 5.3.1一起编译。如何正确实施此操作?

上的程序segfaults
x.w = w;// why does it segfault here?

因为X尚未构造,并且X.W包含垃圾。您需要确保B的构造函数首先称为。

    C(int u, double v, const string& w) : x()
    {
        x.w = w;// why does it segfault here?
        x.u = u;
        x.v = v;
    }

为了正确破坏,您需要在A的驱动器中进行。离开C :: 〜C空,然后添加一个破坏者到a。

~A()
{
    if (!isChar)
    {
        c.x.w.~string();
    }
}

复制A时,您还需要小心,因为有时需要调用字符串的驱动器,有时不会被调用。这样做的一种方法是将新的位置用于覆盖this,并且可以像...

一样实现
A& operator=(const A& o)
{
    if (this != &o)
    {
        this->~A();
        if (o.isChar)
        {
            new (this) A(o.c.y);
        }
        else
        {
            new (this) A(o.c.x.u, o.c.x.v, o.c.x.w);
        }
    }
    return *this;
}

和,移动将类似地实施。但是我将把它作为练习给读者。