如何懒惰地初始化全局变量?
How to lazy init a global var?
我正在制作一个DLL。我想在命名空间中为每个将包含MyTools.h
的编译单元提供一个唯一的全局变量(在我的例子中是IBitmap
结构)。这是我在MyTools.h
中的代码:
namespace MyTools
{
const IBitmap BITMAP_CONTROL_BACKGROUND;
}
它初始化一个"空"变量。我想初始化这个变量,调用 MyClass 的方法(返回IBitmap
)(稍后将实例化),但是当我在每个将使用此变量的进程之前执行此操作时:
BITMAP_CONTROL_BACKGROUND = myClass->LoadIBitmap(CONTROL_BACKGROUND, CONTROL_BACKGROUND_PATH, 1);
编译器告诉我BITMAP_CONTROL_BACKGROUND
是常量,所以我不能。
稍后初始化并保持 var 全局的(最佳)方法是什么?
首先让我告诉你不要这样做。你正在使用一个全局变量(用另一个来初始化它......),那么它就是糟糕的™。是的,您不想在编译单元之间共享该变量,但这会使它更加奇怪(IMO)。
如果您仍在阅读并且我没有说服您不要这样做,那么您可以使用函数来初始化const
表达式。将所有内容放在头文件中:
#pragma once
namespace MyTools {
namespace Impl {
IBitmap InitializeControlBackground();
}
const IBitmap BITMAP_CONTROL_BACKGROUND(Impl::InitializeControlBackground());
}
IBitmap MyTools::Imp::InitializeControlBackground() {
return myClass->LoadIBitmap(CONTROL_BACKGROUND, CONTROL_BACKGROUND_PATH, 1);
}
几点注意事项:
InitializeControlBackground()
在命名空间Impl
嵌套实现中声明,不会污染命名空间MyTools
。- 如果每个编译单元的
InitializeControlBackground()
可能不同,则只需将其移动到 .cpp 而不是 .h。
这里可以使用一个随意的单例,但你需要提供一个工厂对象来初始化实例。如果可以随时创建myClass
:
// Header file.
namespace MyTools
{
const IBitmap * bitmapControlBackground();
}
// Source file.
const IBitmap * MyTools::bitmapControlBackground()
{
// Here is a casual singleton. If multi-thread access is possible,
// here must be a casual way to solve it with mutex.
static const IBitmap instance = MyClass().LoadBitmap(...);
return &instance;
}
如果您有全局myClass
变量:
// Source file.
const IBitmap * MyTools::bitmapControlBackground()
{
// Here is a casual singleton. If multi-thread access is possible,
// here must be a casual way to solve it with mutex.
static const IBitmap instance = myClass->LoadBitmap(...);
return &instance;
}
否则,您必须在每次调用时传递它:
// Header file.
namespace MyTools
{
const IBitmap * bitmapControlBackground(MyClass *creator);
}
// Source file.
const IBitmap * MyTools::bitmapControlBackground(MyClass *creator)
{
// Here is a casual singleton. If multi-thread access is possible,
// here must be a casual way to solve it with mutex.
static const IBitmap instance = creator->LoadBitmap(...);
return &instance;
}
相关文章:
- 为什么C++有不同的变量初始化方式?
- 静态 constexpr 成员变量初始化
- C++不同的变量初始化
- 全局和局部变量初始化与 constexpr 的差异背后的基本原理
- 是变量初始化失败吗?
- 视觉C++:在 DLL 加载期间,全局变量初始化顺序是否具有确定性?
- 类静态变量初始化顺序
- 使用 constinit 变量初始化 constexpr 变量
- 是否可以在不修改父类的情况下将成员变量初始化推迟到继承的类?
- 使用全局变量初始化不同编译单元中的其他全局变量
- 使用默认构造函数引用成员变量初始化错误
- 宏的 if 语句中的变量初始化
- 共享库中 __attribute__((构造函数)) 的全局/静态变量初始化问题
- 静态全局变量初始化顺序
- C++全局变量初始化顺序
- 没有全局变量初始化
- 全局变量初始化
- 生成文件:在全局变量初始化之前通过"make all"命令运行 bash 脚本
- 数学运算中的全局变量初始化,机器做什么
- 共享库中全局变量初始化时出现分段错误