gpt4 book ai didi

c++ - union 成员的析构函数似乎被自动调用

转载 作者:行者123 更新时间:2023-12-01 14:12:48 25 4
gpt4 key购买 nike

我正在尝试实现标记 union 。

我的理解是,在 C++ union 中,非静态成员的非平凡(即非空)析构函数从不调用,因此我们必须自己调用它们。我就是这样做的:

#include <iostream>

class C {
public:
C() {
std::cout << "C Ctor" << std::endl;
}
~C() {
std::cout << "C Dtor" << std::endl;
}
};

class B {
public:
B() {
std::cout << "B Ctor" << std::endl;
}
~B() {
std::cout << "B Dtor" << std::endl;
}
};

struct S {
int type;

union U {
C c;
B b;

U() {

}

~U() {}
} u;

S(int type) : type(type) {
if (type == 0) {
u.c = C();
} else {
u.b = B();
}
}

~S() {
if (type == 0) {
u.c.~C();
} else {
u.b.~B();
}
}
};

int main() {
S s(0);
return 0;
}

但是,输出是:

C Ctor
C Dtor
C Dtor

意思是,C 析构函数被调用了两次,而不是仅仅一次。

发生了什么事?如果您发现我的标记 union 实现存在其他问题,请指出。

最佳答案

S(int type) : type(type) {
if (type == 0) {
u.c = C();
} else {
u.b = B();
}
}

由于您在构造函数的主体中,因此 u.c = C(); 不是初始化而是分配。这意味着您会看到为 C() 调用的构造函数,然后在表达式的末尾调用第一个析构函数调用来销毁该临时函数。我们可以通过添加来看到这一点

C& operator=(const C&) { std::cout << "operator=(const C&)\n"; return *this; }

C 将输出更改为

C Ctor
operator=(const C&)
C Dtor
C Dtor

然后第二个析构函数调用是当 s 超出 main 的范围并运行其析构函数时。


请注意,代码具有未定义的行为。 union 不会激活构造函数中的成员,用户提供的构造函数是你写的,所以当你这样做时

u.c = C();

您正在分配一个尚未激活的对象。您不能修改不存在的对象。

关于c++ - union 成员的析构函数似乎被自动调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62555368/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com