【发布时间】:2021-10-22 09:34:17
【问题描述】:
我有这个例子:
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;
-
我们知道类默认析构函数不知道类的联合类型成员的哪个成员是活动的,这就是我们需要定义析构函数的原因。所以联合的类类型的成员数据不会被自动销毁。那么如果我不显式调用联合的那些类类型成员的析构函数会发生什么?
-
如果我在
Foo析构函数中注释该行或删除析构函数本身会发生什么?是未定义的行为吗? -
我的类
A不通过原始指针管理资源,那么当它的对象是union的成员时,为什么我还要费心显式调用它的析构函数?谢谢!
P.S:我有这个来自 C++ 入门第 5 版第 19.6 章联合:
我们的析构函数检查被销毁的对象是否包含一个字符串。如果是这样,析构函数显式调用字符串析构函数(第 19.1.2 节,第 824 页)以释放该字符串使用的内存。如果联合拥有任何内置类型的成员,则析构函数没有工作可做。
“如果联合拥有任何内置类型的成员,则析构函数没有工作可做。”我认为他可以添加:“或依赖于微不足道的析构函数的类类型”。你怎么看?
【问题讨论】:
-
对于它的价值,您还应该考虑调用
A的析构函数,而a_在您分配给b_之前仍然是活动成员 -
@alterigel:这只是一个示例,以了解如果我不明确调用 dtor 会发生什么。我知道在一个真实的程序中我应该重载复制赋值运算符,并且在赋值之前我应该在 dtor 中检查它。
-
@ItachiUchiwa 换个角度想一想:“嘿,我写了我非常好的 RAII 类,现在有人把它放在
union中,我应该担心吗?” -
如果 A 的析构函数没有被调用,那么效果就是 A 的析构函数没有被调用。这有多大的问题将完全取决于 A 的析构函数会做什么——例如如果 A 是 POD 类,则不会丢失任何有价值的东西,因为 A 的析构函数无论如何都是空操作。 OTOH 例如如果 A 持有一些 A 的析构函数应该释放的资源,那么你就永远泄露了该资源。 (注意即使 A 通过智能指针持有资源,泄漏仍然会发生,因为智能指针的析构函数不会被调用)
-
@JeremyFriesner:我认为这将是最好的答案。那么你会添加它作为答案吗?
标签: c++ class union destructor