Avi*_*ohn 3 c++ union destructor
我正在尝试实施标记联合。
我的理解是,在 C++ 联合中,非静态成员的非平凡(即非空)析构函数永远不会被调用,因此我们必须自己调用它们。这就是我所做的:
#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;
}
Run Code Online (Sandbox Code Playgroud)
但是,输出是:
C Ctor
C Dtor
C Dtor
Run Code Online (Sandbox Code Playgroud)
意思是,C
析构函数被调用了两次,而不是一次。
到底是怎么回事?如果您注意到我标记的联合实施的其他问题,请指出它们。
在
S(int type) : type(type) {
if (type == 0) {
u.c = C();
} else {
u.b = B();
}
}
Run Code Online (Sandbox Code Playgroud)
由于您在构造u.c = C();
函数的主体中,因此不是初始化而是赋值。这意味着您会看到调用了 的构造函数C()
,然后在表达式的末尾调用了第一个析构函数调用来销毁该临时对象。我们可以通过添加来看到这一点
C& operator=(const C&) { std::cout << "operator=(const C&)\n"; return *this; }
Run Code Online (Sandbox Code Playgroud)
到C
这改变了输出到
C Ctor
operator=(const C&)
C Dtor
C Dtor
Run Code Online (Sandbox Code Playgroud)
然后第二个析构函数调用是s
在 main 中超出范围并运行其析构函数时。
请注意,代码具有未定义的行为。联合不会激活构造函数用户提供的构造函数中的成员,因此当您这样做时
u.c = C();
Run Code Online (Sandbox Code Playgroud)
您正在分配给尚未存活的对象。您无法修改非活动对象。
归档时间: |
|
查看次数: |
110 次 |
最近记录: |