如何在 C 中初始化私有静态成员?

新手上路,请多包涵

在 C++ 中初始化私有静态数据成员的最佳方法是什么?我在我的头文件中尝试了这个,但它给了我奇怪的链接器错误:

 class foo
{
    private:
        static int i;
};

int foo::i = 0;

我猜这是因为我无法从类外初始化私有成员。那么最好的方法是什么?

原文由 Jason Baker 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 905
2 个回答

类声明应该在头文件中(如果不共享,则在源文件中)。

文件:foo.h

 class foo
{
    private:
        static int i;
};

但是初始化应该在源文件中。

文件:foo.cpp

 int foo::i = 0;

如果初始化在头文件中,则包含头文件的每个文件都将具有静态成员的定义。因此,在链接阶段,您将收到链接器错误,因为初始化变量的代码将在多个源文件中定义。 static int i 的初始化必须在任何函数之外完成。

注意: Matt Curtis:指出如果静态成员变量是 const 整数类型boolcharchar8_t since C++20], char16_t , char32_t , wchar_t , short , int , longlong long ,或任何实现定义的扩展整数类型,包括任何有符号、无符号和 cv 限定的变体。 )。然后,您可以直接在头文件的类声明中声明和初始化成员变量:

 class foo
{
    private:
        static int const i = 42;
};

原文由 Martin York 发布,翻译遵循 CC BY-SA 4.0 许可协议

以下是一个简单示例中的所有可能性和错误…

 #ifndef Foo_h
#define Foo_h

class Foo
{
  static const int a = 42; // OK
  static const int b {7};  // OK
  //static int x = 42; // ISO C++ forbids in-class initialization of non-const static member 'Foo::x'
  //static int y {7};  // ISO C++ forbids in-class initialization of non-const static member 'Foo::x'
  static int x;
  static int y;
  int m = 42;
  int n {7};
};

// Foo::x = 42;  // error: 'int Foo::x' is private
int Foo::x = 42; // OK in Foo.h if included in only one  *.cpp -> *.o file!
int Foo::y {7};  // OK

// int Foo::y {7};  // error: redefinition of 'int Foo::y'
   // ONLY if the compiler can see both declarations at the same time it,
   // OTHERWISE you get a linker error

#endif // Foo_h

但最好把它放在 Foo.cpp 中。这样您可以单独编译每个文件并稍后链接它们,否则 Foo:x 将出现在多个目标文件中并导致链接器错误。 …

 // Foo::x = 42;  // error: 'int Foo::x' is private, bad if Foo::X is public!
int Foo::x = 42; // OK in Foo.h if included in only one  *.cpp -> *.o file!
int Foo::y {7};  // OK

原文由 cat 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题