c++ - 引用一个可能被破坏的静态对象

标签 c++ c++11 static-variables

假设我有以下代码

Something.hpp

#pragma once

class Something {
public:
    static Something& get();
private: 
    Something();
};

Something.cpp

#include "Something.hpp"
#include <iostream>
using namespace std;

Something& Something::get() {
    static Something something;
    return something;
}
Something::Something() {
    cout << "Something()" << endl;
}

main.cpp

#include <iostream>
using namespace std;

struct SomethingElse {
    ~SomethingElse() {
        Something::get();
        cout << "~SomethingElse" << endl; 
    }
};

void func() {
    static SomethingElse something_else;
    // do something with something_else
}

int main() {
    func();
    return 0;
}

是否可以创建多个 Something 对象实例?该标准是否说明了有关序列化静态对象的销毁的内容?

注意 我知道跨不同翻译单元时文件级静态变量的破坏是未定义的,我想知道在函数范围静态变量(which have the double-checked locking pattern built into the C++ runtime)的情况下会发生什么具有文件级静态变量的相同翻译单元情况,编译器很容易根据变量在代码中的布局方式(静态)确保通过构造和销毁进行序列化,但是当变量是动态延迟创建时会发生什么调用函数?

注意 对于原始变量呢?我们可以期望它们在程序结束之前包含它们的值吗?因为它们不需要被销毁。


编辑

在 cppreference.com ( http://en.cppreference.com/w/cpp/utility/program/exit ) 上找到这个

If the completion of the constructor or dynamic initialization for thread-local or static object A was sequenced-before thread-local or static object B, the completion of the destruction of B is sequenced-before the start of the destruction of A

如果这是真的,那么每个静态对象的销毁都被序列化了?但是我也发现了这个

https://isocpp.org/wiki/faq/ctors#construct-on-first-use-v2这与标准相矛盾

最佳答案

静态(和全局非静态)对象的构造和销毁顺序在 C++ 规范中有明确定义,单个 translation unit !

如果您有多个翻译单元(多个源文件),则未定义 TU 之间的构建/销毁顺序。

因此您显示的代码可以有未定义的行为

关于c++ - 引用一个可能被破坏的静态对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41486703/

相关文章:

C++静态成员变量及其初始化

c++ - "-dndebug"(小写)在 g++ 中有什么作用吗?

C++ 如果我编写一个函数模板并且不请求它的任何实例化,是否会从中生成任何模板函数?

C++ 在里面执行函数和 lambda

c# - 多个线程同时读取静态变量

rust - 如何在函数之间共享静态变量?

c++ - 使用 C++ 插件从 chrome 浏览器下载并运行 exe

c++ - std::async 指定线程的模拟

c++ - std::lock()定义不正确,无法实现还是没用?

C++11 chrono 从数字创建 time_point