目录
静态成员变量
1. 问:这是为什么呢? (以下结束均为个人理解,如有问题,请指教)
2. 使用场景(举一个例子)
代码中需要注意的点:
3.总结:
静态成员函数
使用场景:
静态成员函数中没有this指针:
static关键字用于定义静态成员,在c中我们也是用它来定义。在c中,当我们想要提升局部变量生命周期 -- 就是函数结束后,不释放其内存。
c++类中也可以使用静态,主要有两种: 静态成员函数和静态成员变量
静态成员变量
使用static定义的成员变量, 这种变量它属于类,不属于某一个对象。但是所有的对象都使用同一片空间。
1. 问:这是为什么呢? (以下结束均为个人理解,如有问题,请指教)
1)静态存储区
在内存分区中有一个静态全局区,用于存放全局变量和静态变量,它们的生命周期是其定义到程序结束。
2)static修饰的量
static修饰的量为静态的,所以这样的变量存放在静态常量区,生命周期到程序结束。
3)定义类对象
之前说过类对象,其实就是一个特殊的变量,所以它也有生命周期(也就是存储在哪块内存中)。普通的类对象,其实就是一个局部变量,存储在栈区。
4)类中的变量
当我们定义对象的时候,类中也有局部变量,也在栈区存储。上面说对象也在栈区,所以这些存储在栈区的量,才是对象所拥有的。(因为都存储在栈区)
不同对象中的这些数据是不同的,所以,可以理解为,在栈区中每一个对象变量包含了其自己的局部成员变量的空间。
5)对象共同的
普通局部变量是属于对象的,因为每个对象中的这些量中存储的数据都不同,因为,在栈区中,根据我们创建的对象,它们各自有空间,这些空间用来存储对象自己的成员局部变量的数据。所以,每个对象的数据中的值不同。(因为它们就不是一块内存)。如图:
定义两个对象man1和man2,age,name,salary表示类内非静态数据成员。
static的成员变量,在静态常量区,和对象不在一个区,所以整个类这份数据只有一份(也就是都是一块内存)。 所以对于静态成员,所有对象使用的都是同一片内存。
2. 使用场景(举一个例子)
当我们需要统计我们定义的变量个数的时候, 就可以使用静态的成员变量。
class Human {
public:
Human();
Human(int age,string name);
int getCount(); // 提供接口可以获取Count的值
private:
int age;
string name;
static int Count; // 用来记录创建对象的个数
};
// 静态数据使用是需要初始化
int Human::Count = 0; // 对类的静态数据进行初始化,只能在类外进行初始化
/*因为创建一个对象,就需要调用一种构造函数,所以我们在每一类构造函数中都对Count+1*/
Human::Human(int age, string name) {
this->age = age;
this->name = name;
Count++;
}
Human::Human() {
age = 10;
name = "学习";
Count++;
}
int Human::getCount() {
return Count;
}
// 测试函数
void test() {
Human man1(10,"学习");
Human man2;
}
int main(void) {
Human man1;
test();
cout << man1.getCount() << endl;
system("pause");
return 0;
}
代码中需要注意的点:
1) 因为count只有一片空间,每次都是对一个数据进行+1,所以可以得到对象被创建的个数。
2) static的量初始化,必须在类外进行初始化,不能在类内初始化(类内初始化会出错)。当然也只有静态成员变量可以在类外部初始化。
3) 如果要求严谨,也可以在析构函数中将count-1。
3.总结:
其实使用静态成员是不用想太多, 知道所有对象使用同一份数据就行。
静态成员函数
和静态成员变量,它是属于类的。每个对象共有。
class Human {
public:
Human();
Human(int age,string name);
static int getCount();
private:
int age;
string name;
static int Count;
};
int main(void) {
Human man1;
test();
cout << Human::getCount() << endl; // 可以直接使用类名调用
system("pause");
return 0;
}
静态成员函数可以在类外直接使用类名进行调用。
使用场景:
静态成员变量的弊端:
在我们使用静态成员变量的时候,我们想要获取它的值必须,定义一个对象调用其接口,才能得到值。
有时候,我们在调用类内函数的时候,可能并不想创建对象,这时候就可以将此函数定义成静态的。 --------- 可以在类外直接使用类名调用,不需要创建对象。(当然使用对象名调也可以)。
静态成员函数中没有this指针:
首先,this指针是用来指向当前调用的函数的,而静态成员函数是所有对象共有,所以它不需要使用this来指向调用者。(比如学校的宿舍和水房,宿舍有门牌号,但是水房是共有的就不需要门牌号了)
既然没有this指针,那么在静态函数的内部也就无法访问非静态成员变量。 因为,它无法区分这个变量是哪个对象的。
所以,静态成员函数中只能访问静态成员变量,因为,静态成员变量也是共有的,就不需要this指针。