不销毁作为联合成员的 class 类型的对象是否安全?

Is it safe not to destroy an object of a class type that is a member of a union?

我有这个例子:

struct A{
    A(){std::cout << "A's def-ctor\n";}
    ~A(){std::cout << "A's dtor\n";}
    A(A const&){std::cout << "A's copy-ctor\n";}
    A& operator = (A const&){std::cout << "A's copy-assign op\n"; return *this; }
};

struct Foo{
    Foo() : curMem_(INT), i_(0){}
    ~Foo(){
        if(curMem_ == CLS_A) // If I comment out this line then what happens?
            a_.~A();
    }
    enum {INT, CHAR, CLS_A, BOOL} curMem_;
    union{
        int i_;
        char c_;
        A a_;
        bool b_;
    };
};

Foo f;
f.curMem_ = Foo::CLS_A;
f.a_ = A();

f.curMem_ = Foo::BOOL;
f.b_ = true;

P.S:我从 C++ primer 5th edition Chapter 19.6 unions:

Our destructor checks whether the object being destroyed holds a string. If so, the destructor explicitly calls the string destructor (§ 19.1.2, p. 824) to free the memory used by that string. The destructor has no work to do if the union holds a member of any of the built-in types.

“如果联合拥有任何内置类型的成员,则析构函数无事可做。”我认为他可以添加:“或者 class 类型,这取决于琐碎的析构函数”。你怎么看?

[basic.life]p6中给出的标准的准确写法是:

For an object of a class type, the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released; however, if there is no explicit call to the destructor or if a delete-expression ([expr.delete]) is not used to release the storage, the destructor is not implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.

(强调我的)

“取决于副作用”似乎很模糊,并且有很多关于堆栈溢出的问题讨论这个措辞。你的 A class 的析构函数似乎有调用 I/O 函数的副作用,所以你 运行 似乎陷入了未定义的行为。

即使它不是 UB,如果它是 std::vectorstd::stringstd::fstream,您也会泄漏内存或文件句柄等资源。这完全取决于 class 的析构函数(以及 class 的任何成员)的作用。


因为“我的 class A 不通过原始指针管理资源”,它应该有一个简单的析构函数。在这种情况下,这一点没有实际意义,不调用析构函数就可以了。