一、类的静态成员变量
我们可以在类中通过static关键字声明一个类的静态成员变量,类的静态成员变量的特点:
①所有的类的实例中,共享类中的静态成员变量
②类的静态成员变量在没有类的实例的情况下,依然可以访问
③类的静态成员变量并不完全属于类
class T
{
public:
static int count; //只是普通的说明,并没有给它分配内存空间
int hp;
};
int T::count = 100; //定义(分配内存空间,给初始值)
1.共享性
这个特点使不同对象之间能够通讯(数据共享)
并且不破坏封装性
##(1)接下来用具体例子解释第一句话的意思
int main()
{
T t1, t2; //实例t1、t2
//扩展:hp在定义实例时,才给它分配内存空间
t1.count++;
std::cout << t1.count << std::endl;
std::cout << t2.count << std::endl;
}
int main()
{
T t1, t2, t3;
t1.count++;
std::cout<<&t1.count<<std::endl;
std::cout <<&t2.count<< std::endl;
}
地址相同,说明类中成员变量的实例,是对同一个地方进行操作的
2.可无实例访问
(2)第二句话解释
int main()
{
T::count = 300; //不能写T::hp,因为这种形式是给静态成员的引用
//这种方式叫做访问
//一般直接用这种方式去写,因为这样可直接看出是什么意思,代码可读性高
std::cout << T::count;
}
静态成员在没有实例时就能够访问,说明已经有了内存空间,所以
int T::count = 100;
这句话一般就要放在类的外面,作为全局变量,以便于访问
(在老语法里就这么用)
补充一下,全局变量全部存放在静态存储区,在程序开始执行时给全局变量分配存储区,程序行完毕就释放。
全局变量——堆中
普通变量——栈中
2.1类实例的初始化
#include<iostream>
class T
{
public:
int hp;
int mp;
};
int main()
{
T t1{ 100,200 }; //初始化t1,跟结构体的初始化差不多
std::cout << t1.hp << " " << t1.mp;
}
class T
{
public:
int hp;
private:
int mp;
};
int main()
{
T t1{ 100,200 };
std::cout << t1.hp << " " << t1.mp<<endl;
}
如果这么写,那么就会报错,因为mp放在私有区。
那么删去200呢,还是会报错,这个时候,如果要想初始化这个实例,可以用其它实例来帮忙初始化,就得用到函数。
(这个在下一篇文章——构造函数中会讲到)
2.2结构体变量初始化
struct student
{
char name[20];
};
int main()
{
student stu{"小明" };
cout << stu.name;
}
3.不完全性
(3)第三句话解释
int T::count = 100;
T::要写上去,这就表明了一个归属,就是说这个类里面的count
不然如果直接写int count 就成了直接声明一个变量count
这就是静态成员属于类的地方
int main()
{
std::cout << sizeof(T);
}
根据以往的经验,这个类所占的内存空间应该为8,但是这里结果为4,说明原来的static int count不占T的内存空间
其实static int count本来就是一个全局变量,只是编译器给加了个作用域之类的,限制只能用T或者T的实例来访问它(人为限制)
所以说它不完全属于类
当然,定义static变量在public、private等任何地方都可以定义,只是放在private里,在类之外就访问不到了
在c++的新语法里,是可以在类里面定义静态成员变量的
class T
{
public:
inline static int count{};
int hp;
};
通过这种方式就可以把这个静态变量初始化一下
扩展:static变量统计T的实例个数
lass T
{
public:
static int count;
int hp;
T()
{
count++;
}
int GetCount()
{
return count;
}
~T()
{
count--;
}
};
void test();
int T::count = 0;
T t4;
int main()
{
test();
T t1, t2, t3;
T t5;
std::cout << t1.GetCount();
}
void test()
{
T t1, t2, t3;
}
运行结果是5
如果没有~T()那么就会把test函数里面的也给算进去,但是实际情况是test函数在运行完之后,里面的变量内存空间是会被释放掉的,所以只剩下5个实例
二、类的静态成员常量
const static int count{};
常量用const定义,有了const就不用inline
并且不能计数了,因为常量不能++
至于定义const static是在类里面定义还是在外面定义,其实都可以,但很复杂,因为这跟类型有关,一般基本变量是可以在类里面定义的,但复杂就不行了(这里不细讲)
C++时期新语法,如果想要任何时候都可以行得通,就得用inline
inline const static int count {};