目录
一、类中的静态成员
经过长久的学习,大家都知道在C和C++中有一个static关键字,由这个关键字所修饰的变量的会被放在静态区,其生命周期为整个源程序。而static静态变量由有两个分类,分别是:局部静态变量和全局静态变量。这两个变量的生命周期并无区别,唯一的区别就在于局部静态变量只能在其定义的局部范围内使用,而全局静态变量则可以在全局域使用
假设我们现在有一个类,我们要求统计这个类中所创建的对象数量,我们可以以如下方式统计:
int n = 0;
class Test
{
public:
Test()
:_a(0)
{
++n;
}
Test(Test& t)
{
++n;
}
private:
int _a;
};
int main()
{
Test t1;
cout << n << endl;
return 0;
}
在这个程序中,我们在类的外面定义了一个n,这个n是可以在类里面使用的,我们将这个n放在类的构造和拷贝构造函数中,每调用一次就++,这样我们就可以拿到这个类创建的对象的次数。
但是这个变量n是一个全局变量,是可以被随意调用和修改的,这个n也可能会被外部的使用者无意或有意的修改,导致数据错误。因此,我们最好将这个n放在类里面。可是这也会导致一个问题:将这个变量放在类里面,这就意味着我们会对它进行初始化,每次对象调用都会对n进行一次初始化,这就会导致我们无法拿到正确的数据。为此,类中便有了静态成员变量的概念
1.类中static静态成员变量
类中的静态成员变量存储在静态区中,作用域为整个类。对于上面的那个问题,我们可以以如下方式进行解决:
但是这就有一个问题了,静态成员变量是存储在静态区的,而普通对象创建是创建在栈中的,这就意味着我们创建的对象中不会存在static成员变量。那既然对象中不会存在静态成员变量,理所当然的,构造和拷贝构造函数中就不能对static成员变量进行初始化。那么我们要在哪里对这个成员变量进行初始化呢?C++中规定,在类中的static成员变量在“类外”进行初始化:
class Test
{
public:
Test()
:_a(0)
{
++_N;
}
Test(const Test& t)
{
++_N;
}
private:
int _a;
static int _N;
};
int Test:: _N = 0;
这里有一点要注意,对于其他static局部或全局变量,如果我们不对其进行初始化,编译器会自动将其初始化为0。而类中的static成员变量不同,我们必须要对其初始化,否则会报错。
从类外获取static成员
现在我们通过定义static成员变量的方式解决了统计创建对象个数的问题,那么我们要如何拿到它呢?首先来看如果这个static成员变量是public的
(1)假设static成员是public的
如果在类里面这个static成员变量被设置为public,那我们就可以很简单的从类外获取。
1.直接指定类域进行获取
这里可以直接指定类域进行获取。
但是有没有人感到奇怪,明明外面创建的对象中并不存在static成员变量,那为什么我们依然可以通过对象的方式获取_N的值呢?
这是因为虽然对象中并不存在,但是当调用这个对象时,编译器依然会从类中去寻找数据。既然如此,那我们可以尝试一下用指针的方式能否调用_N。
2.用指针的方式获取
可以看到,这种方式是可行的。但是假如这个指针指向nullptr呢?
依然可以正常运行。这就是因为虽然这个类指针指向空,但调用数据时依然会从类中去查找。
(2)static成员是private的
1.写一个Get_N&#