static
用法
类中的静态成员
在类定义内部,static是为了声明不bound to类实例的成员
语法
static关键词通常会在其他specifiers之前出现,即static data-member
或static member-function
,但也可能出现在specifier sequence的任何位置出现。(最好是在第一个位置)
不能与类名相同!
解释
静态成员不与类的对象关联,是具有静态存储期或regular function的独立变量
regular function指堆区函数
只能声明不能定义
class X
{
static int n; //可以
static int n=1; //不行
}
int X::n=1; //需要在外部定义
类中的声明可以是不完整类型(incomplete type)
struct Foo;
struct S
{
static int a[];// incomplete type,因为没有指定数组大小
static Foo x;// incomplete type,因为结构体Foo没有定义只有声明
static S s;// incomplete type,在自身定义中的声明视为未定义,
//只有在自身定义外的声明,即在自身定义外的第一次声明才会被自动视为定义
}
int S::a[10]; // complete type
struct Foo {};
Foo S::x; // complete type
S S::s; //compete type
然而,如果声明使用了 constexpr 说明符,那么该成员必须声明为拥有完整类型。例如
static constexpr bool has_quiet_NaN = true;
要想引用类中的静态成员,我们可以用两种方式:
- T::m
- E.m E为T的表达式
- E->m E为T*的表达式
但在同一类scope中不需要qulification
struct X
{
static void f();
static int n;
}
// 返回结构体X的函数g()
X g() {return X();}
// 两种调用f()的方法,qualified name法和member access expression法
void f()
{
X::f(); // qulified name
g().f(); // member access expression
}
// 定义类型
int X::n=7; // 跨域定义
void X::f()
{
n=1; // 同域定义
}
静态类型也遵守类成员访问规则private protected public
定义具有静态存储期且进初始化一次的block scope variable
存储类说明符
静态存储期的定义:一个实体具有静态存储期→\rightarrow→该实体在程序运行期间持续存在
p:一个变量属于命名空间作用域
q:事先声明为static或extern
r:一个变量具有线程存储期
t:一个变量具有静态存储期
则p∧q∧¬r→tp\land q\land \lnot r\rightarrow tp∧q∧¬r→t
具有静态存储期的块变量在控制首次经过它的声明时才会被初始化(除非它被零初始化或常量初始化,这可以在首次进入块前进行)。在其后所有的调用中,声明都会被跳过。
静态成员函数
- 静态成员函数与任何对象都不关联,因此调用时没有this指针
- 静态成员函数不能是
virtual, const, volatile, ref-qualified
- 静态成员函数的地址可以存储在常规的函数指针中,但不能存储在成员函数指针中。也就是全局的函数指针可以存储静态成员函数
静态数据成员
- 静态数据成员不关联到任何对象。即使不定义类的任何对象它们也存在
- 静态数据成员不能是
mutable
的。 - 在命名空间作用域中,如果类自身具有外部连接(即不是无名命名空间的成员),那么类的静态数据成员也具有外部连接。
- 局部类(定义于函数内部的类)和无名类,包括无名类的成员类,不能拥有静态数据成员。
常量静态成员
- 如果整型或枚举类型的静态数据成员被声明为 const(且非 volatile),那么它能以其中的每个表达式均为常量表达式的初始化器直接在类定义内初始化
- 如果声明字面类型 (LiteralType) 的静态数据成员为 constexpr,那么它必须以其中的每个表达式均为常量表达式的初始化器直接在类定义内初始化
struct X
{
const static int n=1;
const static int k; // ok
constexpr static int k; // 不可以,必须常量初始化
constexpr static int k=3; // ok
}
const static int X::k=3;