Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何初始化全局变量?_C++_Constants_Global_Lazy Initialization - Fatal编程技术网

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
    命名空间
  • 如果每个编译单元的
    InitializeControlBackground()
    可能不同,则只需将其移动到.cpp而不是.h即可

首先让我告诉你不要这样做。如果你使用一个全局变量(用另一个来初始化它…),那么它就是不好的™. 是的,您不想在编译单元之间共享该变量,但这会使它变得更奇怪(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;
}

这里可以使用临时单例,但需要提供一个工厂对象来初始化实例。如果您可以随时创建
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,我也希望这样做,但是我需要在一个类中使用这样的函数初始化它们,该类稍后将被初始化。