如何在C++中初始化静态const成员?

ana*_*kos 61 c++ static

是否可以在构造函数外部初始化静态const值?可以在找到成员声明的同一地点进行初始化吗?

class A {
private:
  static const int a = 4;
  /*...*/
};
Run Code Online (Sandbox Code Playgroud)

Kla*_*aim 70

是的,你可以但只能用于int类型.如果您希望静态成员是任何其他类型,则必须在cpp文件中的某处定义它.

class A{
private:
 static const int a = 4; // valid
 static const std::string t ; // can't be initialized here
 ...
 ...
};


// in a cpp file where the static variable will exist 
const std::string A::t = "this way it works";
Run Code Online (Sandbox Code Playgroud)

另请注意,此规则已在C++ 11中删除,现在(使用提供该功能的编译器)您可以直接在类成员声明中初始化您想要的内容.

  • 如果这个答案可以扩展到您需要在 c++11 或 c++17 中执行的操作,那就太好了。基本上将@Zhang的评论添加到答案中 (4认同)
  • @anarhikos - 类内初始化仅适用于整数类型.`double`不是一个整体类型. (2认同)
  • @anrhikos:这就是为什么你不应该在类内部定义。您应该在课堂外定义作为练习问题(请参阅我的答案) (2认同)
  • @anarhikos,您需要在静态常量(C++17)或 constexpr 之前内联 (2认同)

小智 33

静态数据成员(仅限C++)

类的成员列表中的静态数据成员的声明不是定义.您必须在命名空间范围内的类声明之外定义静态成员.例如:

class X
{
public:
      static int i;
};
int X::i = 0; // definition outside class declaration
Run Code Online (Sandbox Code Playgroud)

一旦定义了静态数据成员,即使没有静态数据成员类的对象,它也存在.在上面的示例中,即使已经定义了静态数据成员X :: i,也不存在类X的对象.

命名空间范围内的类的静态数据成员具有外部链接.静态数据成员的初始化程序位于声明成员的类的范围内.

静态数据成员可以是任何类型,除了使用const或volatile限定的void或void.您不能将静态数据成员声明为可变.

在程序中只能有一个静态成员的定义.未命名的类,未命名的类中包含的类以及本地类不能具有静态数据成员.

静态数据成员及其初始化程序可以访问其类的其他静态私有成员和受保护成员.以下示例显示了如何使用其他静态成员初始化静态成员,即使这些成员是私有的:

class C {
      static int i;
      static int j;
      static int k;
      static int l;
      static int m;
      static int n;
      static int p;
      static int q;
      static int r;
      static int s;
      static int f() { return 0; }
      int a;
public:
      C() { a = 0; }
      };

C c;
int C::i = C::f();    // initialize with static member function
int C::j = C::i;      // initialize with another static data member
int C::k = c.f();     // initialize with member function from an object
int C::l = c.j;       // initialize with data member from an object
int C::s = c.a;       // initialize with nonstatic data member
int C::r = 1;         // initialize with a constant value

class Y : private C {} y;

int C::m = Y::f();
int C::n = Y::r;
int C::p = y.r;       // error
int C::q = y.f();     // error
Run Code Online (Sandbox Code Playgroud)

C :: p和C :: q的初始化会导致错误,因为y是从C私有派生的类的对象,而C的成员无法访问其成员.

如果静态数据成员是const integral或const枚举类型,则可以在静态数据成员的声明中指定常量初始值设定项.此常量初始值设定项必须是整型常量表达式.请注意,常量初始值设定项不是定义.您仍然需要在封闭的命名空间中定义静态成员.以下示例演示了这一点:

#include <iostream>
using namespace std;

struct X {
  static const int a = 76;
};

const int X::a;

int main() {
  cout << X::a << endl;
}
Run Code Online (Sandbox Code Playgroud)

静态数据成员a声明结束时的标记= 76是一个常量初始值设定项.


Chu*_*dad 13

仅仅为了完整性,我添加了静态模板成员变量.

template<class T> struct X{
   static T x;
};

template<class T> T X<T>::x = T();

int main(){
   X<int> x;
}
Run Code Online (Sandbox Code Playgroud)

  • 感谢 [@Chubsdad](/sf/users/29267731/) 分享!找到正确的语法非常困难。 (2认同)

sbi*_*sbi 6

您无法在构造函数中初始化静态成员.可以在声明中内联初始化的整数类型.必须在(在.cpp)文件中定义其他静态成员:

// .h
class A{
private:
 static const int a = 4;
 static const foo bar;
 ...
 ...
};

// .cpp
const foo A::bar = ...;
Run Code Online (Sandbox Code Playgroud)