c++ - 不销毁作为 union 成员的类类型的对象是否安全?

标签 c++ class destructor unions

我有这个例子:

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;
  • 我们知道类默认析构函数不知道 union 类型的类成员中的哪个成员处于事件状态,这就是为什么我们确实需要定义析构函数的外部版本。所以union的class类型的成员数据不会自动销毁。那么,如果我不显式调用 union 体的那些类类型成员的析构函数,会发生什么情况?

  • 如果我注释掉 Foo 析构函数中的行或删除析构函数本身会发生什么?是未定义的行为吗?

  • 我的类 A 不通过原始指针管理资源,那么当它的一个对象是 union 的成员时,为什么我还要显式地调用它的析构函数?谢谢!

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.

“如果 union 拥有任何内置类型的成员,则析构函数无事可做。”我认为他可以添加:“或依赖于平凡析构函数的类类型”。你怎么看?

最佳答案

[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 类的析构函数似乎具有调用 I/O 函数的副作用,因此您似乎遇到了未定义的行为。

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


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

关于c++ - 不销毁作为 union 成员的类类型的对象是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68868794/

相关文章:

c++ - 需要 4 种颜色渐变逻辑

javascript - 使用它们的类从一组中选择可见的 div

C++ 构造函数和析构函数

c++ - 如何将2个类分成单独的.h文件并正确设置它们

c++ - boost gzip 解压缩字节数组

c++ - 为什么C++不允许派生类在初始化列表中使用基类成员?

python - 创建类遵循哪种策略?

c++ - 为什么调用赋值运算符会触发销毁函数?

c++ - 析构函数——我应该使用 delete 还是 delete[]?

c++ - 快速新运营商问题