gpt4 book ai didi

C++静态变量的初始化(再一次)

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:08:52 25 4
gpt4 key购买 nike

如果我在不同的编译单元中有两个静态变量,那么它们的初始化顺序是没有定义的。这个教训很好学。

我的问题是:当第一个静态变量被初始化时,所有的静态变量都已经分配了吗?换句话说:

static A global_a; // in compilation unit 1
static B global_b; // in compilation unit 2

struct A {
A() { b_ptr = &global_b; }
B *b_ptr;

void f() { b_ptr->do_something(); }
}

int main() {
global_a.f();
}

b_ptr 会指向一 block 有效的内存,在执行 main 函数时分配和初始化 B 吗?在所有平台上?

长话短说:

编译单元1是Qt库。另一个是我的应用程序。我有几个 QObject 派生类,我需要能够通过类名字符串实例化。为此,我想出了一个模板化的工厂类:

class AbstractFactory {
public:
virtual QObject *create() = 0;
static QMap<const QMetaObject *, AbstractFactory *> m_Map;
}
QMap<const QMetaObject *, AbstractFactory *> AbstractFactory::m_Map; //in .cpp

template <class T>
class ConcreteFactory: public AbstractFactory {
public:
ConcreteFactory() { AbstractFactory::m_Map[&T::staticMetaObject] = this; }
QObject *create() { return new T(); }
}

#define FACTORY(TYPE) static ConcreteFactory < TYPE > m_Factory;

然后我在每个 QObject 子类定义上添加这个宏:

class Subclass : public QObject {
Q_OBJECT;
FACTORY(Subclass);
}

最后我可以通过类型名实例化一个类:

QObject *create(const QString &type) {
foreach (const QMetaObect *meta, AbstractFactory::m_Map.keys() {
if (meta->className() == type) {
return AbstractFactory::m_Map[meta]->create();
}
}
return 0;
}

所以这个类得到一个静态的QMetaObject实例:Subclass::staticMetaObject来自 Qt 库 - 它在 Q_OBJECT 中自动生成我认为宏。然后是 FACTORY宏创建静态 ConcreteFactory< Subclass >实例。 ConcreteFactory 在其构造函数中尝试引用 Subclass::staticMetaObject。

我对 linux (gcc) 上的这个实现非常满意,直到我用 Visual Studio 2008 编译它。出于某种原因,AbstractFactory::m_Map 在运行时为空,并且调试器不会在工厂构造函数处中断。

所以这就是引用其他静态变量的静态变量的味道的来源。

我如何优化此代码以避免所有这些陷阱?

最佳答案

是的,标准允许这样做。

[basic.life] 部分中有许多段落开始

Before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any pointer that refers to the storage location where the object will be or was located may be used but only in limited ways.

并且有一个脚注表明这特别适用于您的情况

For example, before the construction of a global object of non-POD class type

关于C++静态变量的初始化(再一次),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4379337/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com