C++保证编译单元(.cpp文件)中的变量按声明顺序初始化.对于编译单元的数量,此规则分别适用于每个(我的意思是类外的静态变量).
但是,变量的初始化顺序在不同的编译单元中是不确定的.
我在哪里可以看到关于gcc和MSVC的这个订单的一些解释(我知道依赖于这是一个非常糟糕的想法 - 它只是为了理解我们在迁移到新的GCC主要和不同操作系统时遗留代码可能遇到的问题) ?
我们遇到了静态初始化命令惨败的一些问题,我正在寻找方法来梳理大量代码以找到可能发生的事件.有关如何有效地做到这一点的任何建议?
编辑:我得到了一些关于如何解决静态初始化顺序问题的好答案,但这不是我的问题.我想知道如何查找受此问题影响的对象.在这方面,Evan的答案似乎是迄今为止最好的答案; 我不认为我们可以使用valgrind,但我们可能有可以执行类似功能的内存分析工具.只有在给定构建的初始化顺序错误的情况下才能捕获问题,并且顺序可以随每个构建而改变.也许有一个静态分析工具可以捕捉到这一点.我们的平台是在AIX上运行的IBM XLC/C++编译器.
我有以下类尝试实现通用的Singleton.
struct BaseObject
{
virtual ~BaseObject() {}
};
class _helper
{
private:
template<typename T> friend class Singleton;
set<BaseObject*> _s;
static _helper& _get()
{
static _helper t;
return t;
}
_helper()
{
cout<<" _helper ctor"<<endl;
}
~_helper()
{
cout<<" _helper dtor"<<endl;
//assert(_s.empty());
}
};
// Singleton<foo>::Instance() returns a unique instance of foo
template <typename T>
class Singleton : virtual private T
{
public:
static T& Instance()
{
static Singleton<T> _T;
return _T;
}
private:
Singleton()
{
cout<<"inserting into helper "<<typeid(T).name()<<" ptr …Run Code Online (Sandbox Code Playgroud) 请考虑以下代码:
{
std::auto_ptr<Something> p1(pSomePointer);
std::auto_ptr<Something> p2(pSomeOtherPointer);
...
}
Run Code Online (Sandbox Code Playgroud)
是否保证在退出示波器时p1析构函数将在p1之前被调用?常识说堆栈变量应首先从堆栈顶部销毁,但C++编译器可以重新排序分配.
好吧,我在自己的项目中使用单例。最常用的单例实现可能是Meyer的单例,也可能是使用std :: call_once或pthread_once的单例。两者对于并行计算都是线程安全的
//Meyer's singleton
class MySingleton{
public:
static MySingleton& getInstance(){
static MySingleton instance;
// volatile int dummy{};
return instance;
}
private:
MySingleton()= default;
~MySingleton()= default;
MySingleton(const MySingleton&)= delete;
MySingleton& operator=(const MySingleton&)= delete;
};
//with call_once
class MySingleton{
public:
static MySingleton& getInstance(){
std::call_once(initInstanceFlag, &MySingleton::initSingleton);
// volatile int dummy{};
return *instance;
}
private:
MySingleton()= default;
~MySingleton()= default;
MySingleton(const MySingleton&)= delete;
MySingleton& operator=(const MySingleton&)= delete;
static MySingleton* instance;
static std::once_flag initInstanceFlag;
static void initSingleton(){
instance= new MySingleton;
}
};
MySingleton* MySingleton::instance= nullptr; …Run Code Online (Sandbox Code Playgroud) 我想知道是否有人可以对c ++中的内存释放进程有所了解.
如果我有一个我声明为静态的结构,那么它的构造函数是第一个执行的东西,它的析构函数是最后执行的东西:
struct initializer execute_before_and_after_main {
initializer() { init(); }
~initializer() { cleanup(); }
}
static initializer execute_around_main;
Run Code Online (Sandbox Code Playgroud)
然后我有类似的东西:
class my_class {
my_object objects[100];
}
extern my_class gobal_my_class;
my_class global_my_class;
Run Code Online (Sandbox Code Playgroud)
主要在这里并不重要:
int main (int argc, char* argv[]) {
....
}
Run Code Online (Sandbox Code Playgroud)
当cleanup()被调用时,是objects现在含有解除分配的/无效的存储器阵列?是否存在c ++在此实现的标准初始化/破坏序列,有人可能指向我?
谢谢
编辑:我理解这种类型的代码可能不是最佳实践,但我仍然想知道行为是否已定义.
我试图找到一种确保静态变量的构造和销毁顺序的好方法。据我所知,静态变量的构造和销毁方式如下:
如果静态变量在不同的文件中被定义为全局空间,那么它们的构造顺序是无法保证的。
但是,如果在函数中定义了静态变量,则在第一次执行达到其声明时构造局部静态变量。
基于上面的规则,我写了下面的c++代码来确保静态变量b总是在静态变量之前被破坏a,在我的实验中保证了构造顺序和破坏顺序:
在档案啊
class A {
public:
SomeClass* GetStatic() {
static SomeClass a;
return &a;
}
}
Run Code Online (Sandbox Code Playgroud)
在文件 Bh 中:
#include "A.h"
class B {
public:
AnotherClass* GetStatic() {
A::GetStatic(); // a dummy call to force the static local variable in
// A::GetStatic() get initialized before the b.
static AnotherClass b;
return &b;
}
}
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,我A::GetStatic();在static AnotherClass b;. 如果规则 3 成立,这确保a在 之前初始化b。并且由于规则 …