总结:
1、静态数据成员和静态成员函数属于整个类而不是某个对象
即使没有定义对象,静态成员也是存在的
2、static 成员类外存储,求类大小,并不包含在内。 (因为存储在全局区,而类一般存储在栈区)
3、静态数据成员在类中说明,在类外定义 并且会给他分配内存空间,并初始化(一经定义则必须初始化)
4、静态数据成员的生存周期一直存在于整个程序的生命周期
4、静态成员函数只能访问静态数据成员(原因:非静态成员函数,在调用时this 指 针被当作参数传进。而静态成员函数属于类,而不属于对象,没有 this 指针)
5、静态成员函数的意义,不在于信息共享,数据沟通,而在于管理静态数据成员, 完成对静态数据成员的封装。
6、静态成员函数可在类内实现也可在类外
6、可以通过类作用域 :: 访问静态数据成员和静态成员函数
7、类,struct占用内存,都采用字节对齐方式计算
通过上面的案例,我们可以的得出:
C++类对象中的成员变量和成员函数是分开存储的
成员变量:
普通成员变量:存储于对象中,与struct变量有相同的内存布局和字节对齐方式
静态成员变量:存储于全局数据区中
成员函数:存储于代码段中。
一、静态数据成员的使用
//声明
static 数据类型 成员变量; //在类的内部
//初始化
数据类型 类名::静态数据成员 = 初值; //在类的外部
//调⽤
类名::静态数据成员
类对象.静态数据成员
1,static 成员变量实现了同类对象间信息共享。
2,static 成员类外存储,求类大小,并不包含在内。
3,static 成员是命名空间属于类的全局变量,存储在 data 区。
4,static 成员只能类外初始化。
5,可以通过类名访问(无对象生成时亦可),也可以通过对象访问。
二、静态成员函数的使用
//声明
static 函数声明
//调⽤
类名::函数调⽤
类对象.函数调⽤
三、静态成员函数与普通成员函数的区别
静态成员函数不包含指向具体对象的指针
普通成员函数包含一个指向具体对象的指针
使用案例1:
#if 1
#include<iostream>
using namespace std;//声明类 只是知道它有哪些数据成员 并没有为数据成员开辟空间
//只有在初始化时 才给数据成员开辟空间
class AA {
public:AA(int a, int b) {m_a = a;m_b = b;}static int m_c; //在全局区申请/开辟空间,只能在类外初始化int get_c() {m_c++;return m_c;}void change_m_d(int d) {m_d = d;}static int get_d() { //加static的目的是为了让类共享m_d++;//cout << m_a << endl; 编译错误 静态成员函数只能通过对象调用非静态数据成员 不能直接调用return m_d;}
private:static int m_d;int m_a;int m_b;
};
//静态成员变量的初始化 只能在类外
int AA ::m_c= 10;
int AA::m_d = 20;void test01() {static int a = 10; //只会初始化一次a++;cout << a << endl;
}
void test02() {test01(); //11test01(); //12//cout << a << endl; 编译错误 a并不是全局变量,所以这个没有a的定义
}
//此时说明此文件的test03函数只能在此文件使用 其他文件不可访问
static void test03() {}
void test04() {AA a1(10, 20);AA a2(100, 200);cout << a1.get_c() << endl; //11cout << a2.get_c() << endl; //12cout << a1.m_c << endl; //12AA::m_c = 100;cout << a1.get_c() << endl; //101cout << AA::m_c << endl; //101
}
void test05() {AA a1(10, 20);AA a2(100, 200);cout << a1.get_d() << endl; //21cout << a2.get_d() << endl; //22//AA::change_m_d(100); 编译错误 此种方式只适用于静态数据成员 或者静态成员函数a1.change_m_d(100);AA::get_d();cout << a1.get_d() << endl; //102cout << a2.get_d() << endl; //103
}
int main() {//test02();//test04();test05();return 0;
}
#endif
使用案例2:
#if 1
#include<iostream>
using namespace std;
class Student {
public:Student(int id, int score) {m_id = id;m_score = score;m_num++;m_sum_score+=score;}static int get_m_num() {return m_num;}static double get_score_average() {return m_sum_score/m_num;}
private:int m_id;int m_score;static int m_num;static double m_sum_score;
};
int Student::m_num = 0;
double Student::m_sum_score = 0;int main() {Student s1(1, 70);Student s2(2, 80);Student s3(3, 90);//cout << "人数和:" << Student::m_num << endl;m_num为私有成员 不可在类外访问cout << "人数和:" << Student::get_m_num() << endl;cout << "平均分:" << Student::get_score_average() << endl;
}
#endif
static占用内存使用案例:
#if 1
#include <iostream>
using namespace std;
class C1
{
public:int i; //4int j; //4int k; //4
}; //12
class C2
{
public:int i;int j;int k;static int m; //4
public:int getK() const { return k; } //4void setK(int val) { k = val; } //4
};
struct S1
{int i;int j;int k;
}; //12
struct S2
{int i;int j;int k;static int m;
}; //12?
int main()
{cout << "c1 : " << sizeof(C1) << endl; //12cout << "c1 : " << sizeof(C2) << endl; //12cout << "c1 : " << sizeof(S1) << endl; //12cout << "c1 : " << sizeof(S2) << endl; //12return 0;
}#endif
参考自 https://www.cnblogs.com/Tempt/p/9987510.html