使用枚举值初始化静态全局常量。这样安全吗?陷阱?

时间:2013-09-13 16:35:28

标签: c++ static enums initialization

如果你想用一个类包装一些枚举类型,例如,围绕它构建一些函数,你可能会遇到以下情况:

main.cpp中:

#include "WrappedEnumConstants.h"

int main(int argc, char * argv[])
{
   WrappedZero.print();
   WrappedOne.print();
}

WrappedEnumConstants.h

#ifndef WRAPEDENUMCONSTANTS_H
#define WRAPEDENUMCONSTANTS_H

#include "WrappedEnum.h"
#include "InternalEnum.h"

static const WrappedEnum WrappedZero(ZeroEnum);
static const WrappedEnum WrappedOne(OneEnum);

#endif

WrappedEnum.h

#ifndef WRAPPEDENUM_H
#define WRAPPEDENUM_H

#include <iostream>
#include "InternalEnum.h"

class WrappedEnum
{
public:
   WrappedEnum(InternalEnum a);
   void print() const;
private:
   InternalEnum a;
};
#endif

WrappedEnum.cpp

#include <iostream>
#include "WrappedEnum.h"

WrappedEnum::WrappedEnum(InternalEnum a) :
   a(a)
{}

void WrappedEnum::print() const {
   std::cout << "WrappedEnum: " << a << std::endl;
}

InternalEnum.h

#ifndef INTERNALENUM_H
#define INTERNALENUM_H
   enum InternalEnum { ZeroEnum, OneEnum};
#endif

我得到的输出就像预期的那样:

WrappedEnum: 0
WrappedEnum: 1

我想知道静态常量WrappedZero和WrappedOne的初始化是否安全。 ZeroEnum和OneEnum的常量是否保证在WrappedZero和WrappedOne之前初始化或者我是否幸运?特别是,我想知道如果你在一个大项目中使用WrappedEnum并将许多东西链接在一起会有什么陷阱。你看到了吗?

枚举常量(如ZeroEnum和OneEnum)和全局“static const int”的初始化是否存在差异?

2 个答案:

答案 0 :(得分:1)

  

ZeroEnum和OneEnum的常量是否保证在WrappedZero和WrappedOne之前初始化或者我只是幸运?

它们是编译时常量,因此根本不会在运行时初始化。随时使用它们是安全的。

  

枚举常量(如ZeroEnum和OneEnum)和全局“static const int”的初始化是否存在差异?

如果使用常量值初始化static const int,则在任何知道其值的代码中它将是编译时常量。否则,它将在程序启动前的静态初始化阶段初始化。在任何一种情况下,随时使用它也是安全的。

如果需要使用运行时值初始化,那么它将在动态初始化阶段(如“包装”对象)初始化,并且您可能会遇到初始化问题顺序。

答案 1 :(得分:0)

是的,有区别。

实例中的枚举类型字段是编译器在编译时未知的,因此在生成代码时,它必须实际访问实例以查找值,生成的代码将变得越来越大。

const int 可以在编译时知道(如果使用常量初始化它),因此编译器可以生成直接使用该值的代码(您也可以使用作为常量表达式,例如在数组声明或模板中)。

另请注意,在静态持续时间实例中包装值时,您会在初始化其他静态持续时间实例期间为谁将使用这些包装值创建问题,因为无法保证初始化顺序。

我不确定为什么你认为把一个包含你需要的东西放在包里的盒子是个好主意。除了编写更多代码并使编译器和用户烦恼之外,你实现这一目标有什么好处?