C++ 如何初始化全局变量?
我正在制作一个动态链接库。我希望在名称空间中为包含C++ 如何初始化全局变量?,c++,constants,global,lazy-initialization,C++,Constants,Global,Lazy Initialization,我正在制作一个动态链接库。我希望在名称空间中为包含MyTools.h的每个编译单元都有一个唯一的全局变量(在我的例子中是一个IBitmapstruct)。这是我在MyTools.h中的代码: namespace MyTools { const IBitmap BITMAP_CONTROL_BACKGROUND; } 哪个初始化是一个“空”变量。我想初始化这个变量,调用MyClass(稍后将实例化)的方法(返回IBitmap),但在使用此变量的每个进程之前执行此操作时: BITMAP_C
MyTools.h
的每个编译单元都有一个唯一的全局变量(在我的例子中是一个IBitmap
struct)。这是我在MyTools.h
中的代码:
namespace MyTools
{
const IBitmap BITMAP_CONTROL_BACKGROUND;
}
哪个初始化是一个“空”变量。我想初始化这个变量,调用MyClass(稍后将实例化)的方法(返回IBitmap
),但在使用此变量的每个进程之前执行此操作时:
BITMAP_CONTROL_BACKGROUND = myClass->LoadIBitmap(CONTROL_BACKGROUND, CONTROL_BACKGROUND_PATH, 1);
编译器告诉我,BITMAP\u CONTROL\u 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
- 如果每个编译单元的
可能不同,则只需将其移动到.cpp而不是.h即可InitializeControlBackground()
如果您仍在阅读,而我没有说服您不要这样做,那么您可以使用函数初始化
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
- 如果每个编译单元的
可能不同,则只需将其移动到.cpp而不是.h即可InitializeControlBackground()
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;
}
这里可以使用临时单例,但需要提供一个工厂对象来初始化实例。如果您可以随时创建
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++中查找单体设计模式及其实现。@ ILOXXI:Singleton是用于<代码>类< /代码>。我只需要namespace/vars,而不是整个类。删除常量,使用指针(smartpointer),在创建时使用null进行初始化,以便检查它是否已经初始化。根据需要初始化指针…解决方案:不使用全局状态;)@西蒙克雷默:我不能删除
const
<代码>IBitmap*位图\控制\背景代码>将给我链接器错误,因为它在我多次引用时已经定义。HLoopUp单例设计模式及其实现在C++中。@ ILOXXI:Singleton是针对<代码>类< /C>。我只需要namespace/vars,而不是整个类。删除常量,使用指针(smartpointer),在创建时使用null进行初始化,以便检查它是否已经初始化。根据需要初始化指针…解决方案:不使用全局状态;)@西蒙克雷默:我不能删除const
<代码>IBitmap*位图\控制\背景将给我链接器错误,因为当我多次包含相同的链接器时,它已经被定义。为什么“不要这样做”?如果我需要初始化在“未来”对象中共享的同一个对象,为什么这会带来痛苦?第一部《全局变量的罪恶》可能值得一读,因为每个共享对象都增加了依赖性和耦合性。一个全局变量可以被任何地方访问,然后每个(不受控制的)访问将与所有其他访问相耦合(它可能会打开您的代码以适应竞争条件)。这不是我的示例!在这里,我定义了一个“全局”工具,它定义了一个特定的元素,这个元素来自于一种我可以在任何地方使用(并且从不编辑)的“工具”。我正在研究这个框架,它使用了许多这种方法:正如你所看到的,每个颜色元素都是全局的,我可以随时调用它。对于IBitmap,我也希望这样做,但是我需要在一个类中使用这样一个函数来初始化它们,这个类稍后将被初始化?如果我需要初始化在“未来”对象中共享的同一个对象,为什么这会带来痛苦?第一部《全局变量的罪恶》可能值得一读,因为每个共享对象都增加了依赖性和耦合性。一个全局变量可以被任何地方访问,然后每个(不受控制的)访问将与所有其他访问相耦合(它可能会打开您的代码以适应竞争条件)。这不是我的示例!在这里,我定义了一个“全局”工具,它定义了一个特定的元素,这个元素来自于一种我可以在任何地方使用(并且从不编辑)的“工具”。我正在研究这个框架,它使用了许多这种方法:正如你所看到的,每个颜色元素都是全局的,我可以随时调用它。对于IBitmap,我也希望这样做,但是我需要在一个类中使用这样的函数初始化它们,该类稍后将被初始化。