首页 > 解决方案 > 破坏局部静态对象

问题描述

考虑这样的情况:

#include <iostream>

int foo() {
    static struct S {
        int value;
        S(int a): value(a) {}~S() {
            std::cout << "End is nigh";
        }
    }
    s(42);
    return s.value;
}

int main() {
    return foo();
}

在编译器的实现中,我在代码中研究了这些结果,这些代码设置S::~S()为调用_atexit,即本地静态对象将在退出后的某个时刻停止存在main()

如果全局静态/外部作用域中的对象的析构函数调用具有函数局部静态作用域的函数,根据定义,该函数在第一次执行进入此作用域时被构造并且来自析构函数的调用是第一次?这也可能是对象函数局部静态作用域的析构函数在函数局部静态作用域中构造另一个对象的情况。

这可能是代码库依赖于 Scott Meyers 的单例实现的多个实例的情况,其中对象实例是函数局部静态变量。我不确定如果这样的单例必须在这个执行阶段访问标准流,那么保证会发生什么,是否确定它们在atexit处理程序之后何时停止运行。

标签: c++singleton

解决方案


这是一个已知解决方案的已知问题,不幸的是它相当复杂。我所知道的最好的方法是 Modern C++ Design 的Phoenix Singleton。简而言之,您可以依赖非类单例的值,并且可以重用 的内存在同一位置s重新创建对象。S

另一种方法是用其余单例共同拥有的对象替换一些实用程序单例,即通过shared_ptr. 这将在最后一个单例超出范围后被删除。


推荐阅读