简体   繁体   English

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

[英]How to initialize a static const member in C++?

Is it possible to initialize a static const value outside of the constructor? 是否可以在构造函数外部初始化静态const值? Can it be initialized at the same place where member declarations are found? 可以在找到成员声明的同一地点进行初始化吗?

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

YES you can but only for int types. 是的,你可以但只能用于int类型。 If you want your static member to be any other type, you'll have to define it somewhere in a cpp file. 如果您希望静态成员是任何其他类型,则必须在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中删除,现在(使用提供该功能的编译器)您可以直接在类成员声明中初始化您想要的内容。

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. 静态数据成员可以是任何类型,除了使用const或volatile限定的void或void。 You cannot declare a static data member as mutable. 您不能将静态数据成员声明为可变。

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. 如果静态数据成员是const integral或const枚举类型,则可以在静态数据成员的声明中指定常量初始值设定项。 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: 以下示例演示了这一点:

#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是一个常量初始值设定项。

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;
}

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 = ...;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM