如何在标头中初始化类变量?

时间:2012-07-05 12:38:21

标签: c++ class variables linker initialization

我正在编写一个库,用户可以在其中定义任意结构并将它们传递给我的库,然后从静态成员获取结构的内存布局,这种结构必须具有约定。

例如:

struct CubeVertex {
  // This is, per convention, required in each structure to describe itself
  static const VertexElement Elements[];

  float x, y, z;
  float u, v;
};

const VertexElement CubeVertex::Elements[] = {
  VertexElement("Position", VertexElementType::Float3),
  VertexElement("TextureCoordinates", VertexElementType::Float2),
};

C ++最佳实践建议我将静态变量及其初始化移动到我的源(.cpp)文件中。但是,我希望保持变量初始化尽可能接近结构,因为每当结构发生变化时,变量也必须更新。

是否有可移植的( = MSVC + GCC至少)方式在头文件中声明这样的变量而不会导致链接器出现含糊不清的符号/重定义错误?

2 个答案:

答案 0 :(得分:3)

这里你可以做的是使用匿名命名空间。

将所有内容包装到“namespace {...};”然后你可以像平常那样访问CubeVertex :: Elements。

但是,每次包含头文件时,都会创建一个新的静态数据实例,该头文件会添加到可执行文件的文件大小。

它对如何使用类/结构也有一些限制,因为你不能从另一个文件调用该类的函数(在这种特殊情况下这不会是一个问题)。

答案 1 :(得分:3)

考虑一个简单的吸气剂。

struct CubeVertex {
    static const std::array<VertexElement, N>& GetElements() {
         static const std::array<VertexElement, N> result = {
             //..
         };
         return result;
    }
    //..
}

直接好处:没有阵列到指针衰减。