如何初始化c++中的静态const成员?

时间:2022-06-08 16:57:46

Is it possible to initialize a static const value outside of the constructor? Can it be initialized at the same place where member declarations are found?

是否可以在构造函数外部初始化一个静态const值?是否可以在找到成员声明的相同位置初始化它?

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

4 个解决方案

#1


57  

YES you can but only for int types. If you want your static member to be any other type, you'll have to define it somewhere in a cpp file.

是的,只能对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";

Also, note that this rule have been removed in C++11, now (with a compiler providing the feature) you can initialize what you want directly in the class member declaration.

另外,请注意,在c++ 11中已经删除了这条规则,现在(有一个编译器提供这个特性)您可以在类成员声明中直接初始化您想要的内容。

#2


27  

Static data members (C++ only)

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

The declaration of a static data member in the member list of a class is not a definition. You must define the static member outside of the class declaration, in namespace scope. For example:

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

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

Once you define a static data member, it exists even though no objects of the static data member's class exist. In the above example, no objects of class X exist even though the static data member X::i has been defined.

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

Static data members of a class in namespace scope have external linkage. The initializer for a static data member is in the scope of the class declaring the member.

名称空间范围中的类的静态数据成员具有外部链接。静态数据成员的初始化器在声明成员的类的范围内。

A static data member can be of any type except for void or void qualified with const or volatile. You cannot declare a static data member as mutable.

除了具有const或volatile限定的void或void之外,静态数据成员可以是任何类型。不能将静态数据成员声明为可变的。

You can only have one definition of a static member in a program. Unnamed classes, classes contained within unnamed classes, and local classes cannot have static data members.

程序中只能有一个静态成员的定义。未命名类、包含在未命名类中的类和本地类不能有静态数据成员。

Static data members and their initializers can access other static private and protected members of their class. The following example shows how you can initialize static members using other static members, even though these members are private:

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

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

The initializations of C::p and C::q cause errors because y is an object of a class that is derived privately from C, and its members are not accessible to members of C.

C::p和C::q的初始化会导致错误,因为y是一个类的对象,这个类是由C派生出来的,它的成员是C成员不可访问的。

If a static data member is of const integral or const enumeration type, you may specify a constant initializer in the static data member's declaration. This constant initializer must be an integral constant expression. Note that the constant initializer is not a definition. You still need to define the static member in an enclosing namespace. The following example demonstrates this:

如果静态数据成员属于const积分或const枚举类型,您可以在静态数据成员的声明中指定一个常量初始化器。这个常量初始化器必须是一个积分常量表达式。注意,常量初始化器不是定义。您仍然需要在封闭的名称空间中定义静态成员。下面的例子说明了这一点:

#include <iostream>
using namespace std;

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

const int X::a;

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

The tokens = 76 at the end of the declaration of static data member a is a constant initializer.

在声明静态数据成员a的末尾,令牌= 76是一个常量初始化器。

#3


10  

Just for the sake of completeness, I am adding about the static template member variables.

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

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

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

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

#4


3  

You cannot initialize static members within constructors. Integral types you can initialize inline at their declaration. Other static members must be defined (in a .cpp) file:

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

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

// .cpp
const foo A::bar = ...;

#1


57  

YES you can but only for int types. If you want your static member to be any other type, you'll have to define it somewhere in a cpp file.

是的,只能对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";

Also, note that this rule have been removed in C++11, now (with a compiler providing the feature) you can initialize what you want directly in the class member declaration.

另外,请注意,在c++ 11中已经删除了这条规则,现在(有一个编译器提供这个特性)您可以在类成员声明中直接初始化您想要的内容。

#2


27  

Static data members (C++ only)

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

The declaration of a static data member in the member list of a class is not a definition. You must define the static member outside of the class declaration, in namespace scope. For example:

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

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

Once you define a static data member, it exists even though no objects of the static data member's class exist. In the above example, no objects of class X exist even though the static data member X::i has been defined.

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

Static data members of a class in namespace scope have external linkage. The initializer for a static data member is in the scope of the class declaring the member.

名称空间范围中的类的静态数据成员具有外部链接。静态数据成员的初始化器在声明成员的类的范围内。

A static data member can be of any type except for void or void qualified with const or volatile. You cannot declare a static data member as mutable.

除了具有const或volatile限定的void或void之外,静态数据成员可以是任何类型。不能将静态数据成员声明为可变的。

You can only have one definition of a static member in a program. Unnamed classes, classes contained within unnamed classes, and local classes cannot have static data members.

程序中只能有一个静态成员的定义。未命名类、包含在未命名类中的类和本地类不能有静态数据成员。

Static data members and their initializers can access other static private and protected members of their class. The following example shows how you can initialize static members using other static members, even though these members are private:

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

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

The initializations of C::p and C::q cause errors because y is an object of a class that is derived privately from C, and its members are not accessible to members of C.

C::p和C::q的初始化会导致错误,因为y是一个类的对象,这个类是由C派生出来的,它的成员是C成员不可访问的。

If a static data member is of const integral or const enumeration type, you may specify a constant initializer in the static data member's declaration. This constant initializer must be an integral constant expression. Note that the constant initializer is not a definition. You still need to define the static member in an enclosing namespace. The following example demonstrates this:

如果静态数据成员属于const积分或const枚举类型,您可以在静态数据成员的声明中指定一个常量初始化器。这个常量初始化器必须是一个积分常量表达式。注意,常量初始化器不是定义。您仍然需要在封闭的名称空间中定义静态成员。下面的例子说明了这一点:

#include <iostream>
using namespace std;

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

const int X::a;

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

The tokens = 76 at the end of the declaration of static data member a is a constant initializer.

在声明静态数据成员a的末尾,令牌= 76是一个常量初始化器。

#3


10  

Just for the sake of completeness, I am adding about the static template member variables.

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

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

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

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

#4


3  

You cannot initialize static members within constructors. Integral types you can initialize inline at their declaration. Other static members must be defined (in a .cpp) file:

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

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

// .cpp
const foo A::bar = ...;