静态数据成员初始化 [英] Static Data Member Initialization

查看:223
本文介绍了静态数据成员初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么静态数据成员初始化必须在类外?

Why must static data member initialization be outside the class?

class X
{
public:
      int normalValue = 5; //NSDMI
      static int i;
};

int X::i = 0;

为什么静态数据成员(这里是i)只是一个声明而不是一个定义? / p>

Why is the static data member (here "i") only a declaration, not a definition?

推荐答案

区分 initializer 定义。此修改后的代码有效,初始值设置在类定义中:

It's important to distinguish the initializer which says what its initial value is, and the definition. This modified code is valid, with the initializer in the class definition:

class X
{
public:
  int normalValue = 5;
  static const int i = 0;       // declaration, with initializer
};

const int X::i;                 // definition

这是因为变量必须在内存中有一个地址(除非它只在有限的情况下使用,比如在编译时常数表达式中。)

That's because a variable must have an address in memory (unless it's only used in limited situations, such as in compile-time constant expressions.)

非静态成员变量存在于它所属的对象中,因此其地址取决于对象的地址包含它。每次创建新的 X 时,您还创建了一个新的 X :: normalValue 变量。非静态数据成员的生命周期始于类的构造函数。 NSDMI语法与内存中变量的地址没有任何关系,它只是允许你在一个地方提供一个初始值,而不是在每个构造函数中使用显式构造函数初始化列表重复它。

A non-static member variable exists inside the object it is a member of, so its address depends on the address of the object that contains it. Every time you create a new X you also create a new X::normalValue variable. The non-static data member's lifetime begins with the class' constructor. NSDMI syntax doesn't have anything to do with the variable's address in memory, it just allows you to provide an initial value in one place, instead of repeating it in every constructor with an explicit constructor initializer list.

另一方面,静态成员变量不包含在类的实例中,它独立于任何单个实例存在,并且在程序的开始处存在于固定地址。为了使静态成员变量(或任何其他全局对象)获得唯一的地址,链接器必须在一个对象文件中看到静态变量的一个定义,并为它分配一个地址。

On the other hand, a static member variable is not contained within an instance of the class, it exists independently of any single instance and exists from the start of the program, at a fixed address. In order for a static member variable (or any other global object) to get a unique address the linker must see exactly one definition of the static variable, in exactly one object file, and assign it an address.

由于静态变量只需要一个对象文件中的一个定义,因此允许在类中提供该定义是没有意义的,因为类定义通常存在于头文件中,在多个目标文件中。因此,虽然你可以在类中提供一个初始化器,你仍然需要在某个地方定义静态数据成员。

Because a static variable needs exactly one definition in exactly one object file, it doesn't make sense to allow that definition to be provided in the class, since class definitions typically exist in header files and are included in multiple object files. So although you can provide an initializer in the class, you still need to define the static data member somewhere.

你也可以看看它像声明一个 extern 变量:

You can also look at it like declaring an extern variable:

namespace X {
  extern int i;
}

这声明了变量,但程序中必须有一个定义:

This declares the variable, but there must be a definition somewhere in the program:

int X::i = 0;

这篇关于静态数据成员初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆