为什么静态数据成员的初始化必须在类外面进行?
class X
{
public:
int normalValue = 5; //NSDMI
static int i;
};
int X::i = 0;
为什么静态数据成员(这里是“i”)只是声明而不是定义?
区分 初始化程序(initializer)和 定义 是很重要的。下面这段经过修改后的代码是有效的,在类定义中加入了初始化程序:
class X
{
public:
int normalValue = 5;
static const int i = 0; // declaration, with initializer
};
const int X::i; // definition
即在类外定义成员变量是定义而不是初始化,因为变量必须在内存中有地址(除非仅用于编译时常量表达式等受限情况),非静态成员变量存在于其所属对象内部,其地址取决于包含它的对象的地址。每次创建新的 X 对象时,也会创建一个新的 X::normalValue 变量。非静态数据成员的生命周期始于类的构造函数。 NSDMI 语法与变量在内存中的地址无关,它只允许您在一个地方提供初始值,而无需在每个具有显式构造函数初始化器列表的构造函数中重复。与之相反,静态成员变量不包含在类的实例中,它独立于任何单个实例而存在,并且从程序开始时就存在于固定地址。为了使静态成员变量(或任何其他全局对象)获得唯一地址,链接器必须在恰好一个对象文件中看到静态变量的恰好一个定义,并分配一个地址。因为静态变量需要恰好一个对象文件中的恰好一个定义,所以允许该定义在类中没有意义,因为类定义通常存在于头文件中并包含在多个对象文件中。因此,尽管可以在类中提供初始化程序,但仍然需要在其他地方定义静态数据成员。也可以将其视为声明 extern 变量:namespace X {
extern int i;
}
这声明了一个变量,但程序中必须有一个定义:
int X::i = 0;
i
是一个静态数据成员,那么它不需要是const
或constexpr
吗? - Johannes Schaub - litbX::i
变量。不应该像这样:“每次创建新的X时,也会创建一个新的X::normalValue
变量”。 - Rndp13i
不是静态的,则…”还是只是愚蠢,我已将其更改为normalValue
,因为这更清晰,谢谢。 - Jonathan Wakely如果一个静态数据成员(如C++11中定义的odr-used)被使用,则需要为其提供单独的定义,因为该定义必须存在于一个且仅有一个翻译单元中。静态类数据成员基本上是在类作用域中声明的全局对象(全局变量)。编译器希望您选择一个特定的翻译单元来保存每个全局对象的实际“主体”。您需要决定将实际对象放置在哪个翻译单元中。
struct A
{
const static int i = 1;
};
然而,这只是一个声明而不是定义。如果您要在某个地方使用 i
的地址,仍然需要定义它。
f(int);
g(int&);
X<A::i> x; // Okay without definition for template arguments
char a[A::i]; // Okay without definition, just using value as constant expression
&A::i; // Need a definition because I'm taking the address
f(A::i); // Okay without definition for pass by value
g(A::i); // Need a definition with pass by reference
当编译器从一个单元(极度简化:一个cpp文件及其所有包含的头文件)生成二进制代码时,它将为静态变量发出一个符号,并最终为该变量发出初始化代码。
静态变量符号可以在多个单元中声明,但不能多次初始化。
因此,您必须确保初始化代码仅针对单个单元发出。这意味着静态变量必须在一个单元中定义。
如果静态数据成员是const整数或const枚举类型,则其在类定义中的声明可以指定一个常量初始化器,该初始化器应为整数常量表达式(5.19)
struct Foo {
static const int j = 42; // OK
};
静态数据成员
#include<iostream.h>
#include<conio.h>
class static_var
{
static int count; //static member of class
public :
void incr_staticvar()
{
count++;
}
void outputc()
{
cout<<"Value of Static variable Count :- "<<count<<endl;
}
};
int static_var::count;
void main()
{
clrscr();
static_var obj1,obj2,obj3,obj4;
obj1.incr_staticvar();
obj2.incr_staticvar();
obj3.incr_staticvar();
obj4.incr_staticvar();
cout<<"\nAfter Increment of static variable by Four Different objects is :-\n";
obj1.outputc ( );
obj2.outputc ( );
obj3.outputc ( );
obj4.outputc ( );
getch();
}
static const int i = 10
。 - Charles Beattie