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


74

是否可以在构造函数之外初始化静态const值?可以在找到成员声明的位置将其初始化吗?

class A {
private:
  static const int a = 4;
  /*...*/
};

11
是的,您所拥有的有效(但仅适用于整数类型)。
UncleBens

3
只是想补充一点static,它与构造函数无关,因为static成员不是特定于给定实例的,而是存在于其外部的。
ereOn 2010年

实际上,您必须在类构造函数之外初始化const statics。否则它将不是const static。杜西?
John Dibling 2010年

Answers:


86

是的,您可以但仅适用于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";

另外,请注意,此规则已在C ++ 11中删除,现在(通过提供此功能的编译器),您可以直接在类成员声明中初始化所需的内容。


2
@anarhikos-类内初始化仅适用于整数类型。double不是整数类型。
Brian Neal 2010年

1
@anrhikos:这就是为什么您不应该在类中定义的原因。您应该根据实际情况在课堂外进行定义(请参阅我的答案)

如果我不想分配值怎么办?如果我只想运行默认构造函数怎么办?如果不分配任何内容,则会收到有关在类外重新声明变量的错误。
Ben Farmer

1
@anarhikos,您需要在静态const(C ++ 17)或constexpr之前进行内联
Zhang Zhang

34

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

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

class X
{
public:
      static int i;
};
int X::i = 0; // definition outside class declaration

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

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

静态数据成员可以是任何类型,但void或用const或volatile限定的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

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

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

#include <iostream>
using namespace std;

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

const int X::a;

int main() {
  cout << X::a << endl;
}

静态数据成员a的声明结尾处的令牌= 76是常量初始化程序。


16

为了完整起见,我添加了静态模板成员变量。

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

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

int main(){
   X<int> x;
}

感谢@Chubsdad的分享!很难找到正确的语法。
用户

7

您不能在构造函数中初始化静态成员。您可以在声明时内联初始化整数类型。必须在.cpp文件中定义其他静态成员:

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

// .cpp
const foo A::bar = ...;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.