如何懒惰地初始化全局变量?

How to lazy init a global var?

本文关键字:全局变量 初始化 何懒惰      更新时间:2023-10-16

我正在制作一个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;
}