【发布时间】:2018-05-07 13:58:13
【问题描述】:
如果类Foo 有一个静态成员变量Bar,我希望Bar 的析构函数仅在Foo 的析构函数的最后一个实例运行后运行。下面的代码 sn-p 不会发生这种情况(gcc 6.3,clang 3.8):
#include <memory>
#include <iostream>
class Foo;
static std::unique_ptr<Foo> foo;
struct Bar {
Bar() {
std::cout << "Bar()" << std::endl;
}
~Bar() {
std::cout << "~Bar()" << std::endl;
}
};
struct Foo {
Foo() {
std::cout << "Foo()" << std::endl;
}
~Foo() {
std::cout << "~Foo()" << std::endl;
}
static Bar bar;
};
Bar Foo::bar;
int main(int argc, char **argv) {
foo = std::make_unique<Foo>();
}
输出:
Bar()
Foo()
~Bar()
~Foo()
为什么这里的破坏顺序不是构造的逆序?
如果~Foo() 使用Foo::bar 这是删除后的使用。
【问题讨论】:
-
您是否尝试过让
~Foo()使用bar数据? -
是的,这就是我提出这个问题的原因。它不会改变行为,并导致使用被破坏的对象。
-
语言中没有机制可以确保在所有类实例被销毁后发生某些事情。类不维护其实例的计数器或类似的东西。
-
@n.m.不,但编译器知道在运行
Foo()之前构造Foo::bar(允许在Foo()中安全使用Foo::bar- 人们希望这种行为也适用于~Foo()。 -
编译器只知道静态对象,它们的销毁顺序与它们的类型无关。
标签: c++