在 C++ 中定义静态成员

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3536372/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 13:03:30  来源:igfitidea点击:

Defining static members in C++

c++static

提问by Jaguar

I am trying to define a public static variable like this :

我正在尝试定义一个像这样的公共静态变量:

public :
         static int j=0;        //or any other value too

I am getting a compilation error on this very line : ISO C++ forbids in-class initialization of non-const static member `j'.

我在这一行收到一个编译错误:ISO C++ 禁止非常量静态成员 `j' 的类内初始化。

  1. Why is it not allowed in C++ ?

  2. Why are const members allowed to be initialized ?

  3. Does this mean static variables in C++ are not initialized with 0 as in C?

  1. 为什么在 C++ 中不允许?

  2. 为什么允许初始化 const 成员?

  3. 这是否意味着 C++ 中的静态变量不像在 C 中那样用 0 初始化?

Thanks !

谢谢 !

采纳答案by Eugen Constantin Dinca

(1.) Why is it not allowed in C++ ?

(1.) 为什么在 C++ 中是不允许的?

From Bjarne Stroustrup's C++ Style and Technique FAQ:

来自Bjarne Stroustrup 的 C++ 风格和技术常见问题解答

A class is typically declared in a header file and a header file is typically included into many translation units. However, to avoid complicated linker rules, C++ requires that every object has a unique definition. That rule would be broken if C++ allowed in-class definition of entities that needed to be stored in memory as objects.

(2.) Why are const members allowed to be initialized ?

类通常在头文件中声明,而头文件通常包含在许多翻译单元中。但是,为了避免复杂的链接器规则,C++ 要求每个对象都有唯一的定义。如果 C++ 允许需要作为对象存储在内存中的实体的类内定义,那么这条规则就会被打破。

(2.) 为什么允许初始化 const 成员?

[dirkgently said it better]

[直接说得更好]

(3.) Does this mean static variables in C++ are not initialized with 0 as in C?

(3.) 这是否意味着 C++ 中的静态变量不像在 C 中那样用 0 初始化?

As far as I know, as long as you declare the static member var in a .cpp it will be zero-initialized if you don't specify otherwise:

据我所知,只要您在 .cpp 中声明静态成员 var,如果您没有另外指定,它将被零初始化:

// in some .cpp
int Test::j; // j = int();

回答by Dennis Miller

You will have to initialize the static variable in a .cpp file and not in the class declaration.

您必须在 .cpp 文件中而不是在类声明中初始化静态变量。

When you declare a static variable in the class, it can used without instantiating a class.

当您在类中声明静态变量时,它可以在不实例化类的情况下使用。

//Header file
class Test
{
  public:
    static int j;
};

//In cpp file

//Initialize static variables here.
int Test::j = 0;

//Constructor
Test::Test(void)
{
   //Class initialize code
}

回答by dirkgently

Why is it not allowed in C++ ?

为什么在 C++ 中不允许?

Until and unless you define it, the variable doesn't become a l-value.

除非您定义它,否则变量不会成为左值。

Why are const members allowed to be initialized ?

为什么允许初始化 const 成员?

Even in this case, a definition is required if you are going to take the address of the variable.

即使在这种情况下,如果要获取变量的地址,也需要定义。

9.4.2 Static data members

2The declaration of a static data member in its class definition is not a definition and may be of an incomplete type other than cv-qualified void. The definition for a static data member shall appear in a namespace scope enclosing the member's class definition. In the definition at namespace scope, the name of the static data member shall be qualified by its class name using the :: operator. The initializer expression in the definition of a static data member is in the scope of its class

9.4.2 静态数据成员

2静态数据成员在其类定义中的声明不是定义,并且可能是除 cv 限定的 void 之外的不完整类型。静态数据成员的定义应出现在包含成员类定义的命名空间范围内。在命名空间范围的定义中,静态数据成员的名称应使用 :: 运算符由其类名限定。静态数据成员定义中的初始化表达式在其类的范围内

Also, this is primarily an usage artifact so that you can write:

此外,这主要是一个使用工件,因此您可以编写:

class S {
      static const int size = 42;
      float array[ size ];
};

Does this mean static variables in C++ are not initialized with 0 as in C?

这是否意味着 C++ 中的静态变量不像在 C 中那样用 0 初始化?

No they are:

不,是他们:

3.6.2 Initialization of non-local variables

Variables with static storage duration (3.7.1) or thread storage duration (3.7.2) shall be zeroinitialized (8.5) before any other initialization takes place.

3.6.2 非局部变量的初始化

具有静态存储持续时间 (3.7.1) 或线程存储持续时间 (3.7.2) 的变量应在任何其他初始化发生之前进行零初始化 (8.5)。

Though things get a bit more trickier in C++0x. All literal types can now be initialized (as opposed to only integral types in the current standard) which would mean that all scalar types (floats included) and some class types can now be initialized using an initializer in the declaration.

尽管在 C++0x 中事情变得更加棘手。现在可以初始化所有文字类型(与当前标准中的仅整数类型相反),这意味着现在可以使用声明中的初始化程序来初始化所有标量类型(包括浮点数)和某些类类型。

回答by tc.

The short answer:

简短的回答:

It's equivalent to saying extern int Test_j = 0;.

相当于说extern int Test_j = 0;

If it did compile, what would happen? Every source file including your class's header file would define a symbol called Test::j initialized to 0. The linker tends not to like that.

如果它确实编译了,会发生什么?每个源文件,包括你的类的头文件,都会定义一个名为 Test::j 的符号,初始化为 0。链接器往往不喜欢这样。

回答by Muhammad Rehan

class GetData        
{    
private:     
static int integer;   //Static variable must be defined with the extension of keyword static;      
public:      
static void enter(int x)      
{       
integer = x;  //static variable passed through the static function    
}
static int  show()   //declared and defined
{
    return integer;   //will return the integer's value
}        
};        
int GetData::integer = 0;    //Definition of the static variable       
int main()      
{      
   GetData::enter(234);    //value has been passed through the static function enter. Note that class containing static variables may not have the object in main. They can be called by scope resolution operator in main.
   cout<<GetData::show();      
}