具体看下面的程序就很清楚了,程序自己写的,下面一段文字大部分复制粘贴的,原文章在下https://blog.csdn.net/Shrimp_millet/article/details/95040735?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_default&utm_relevant_index=1
数据成员:
静态数据成员是类的一部分,为类的所有实例共享(静态区),有时候可以替换全局变量,所有实例都可以去更改它;非静态数据成员,类的每个实例都有一份拷贝(动态区),随着实例不同而不同。
静态数据成员的访问:
静态数据成员是类的一部分,在产生任何实例之前已经存在。
函数成员(都在代码区):
静态函数成员与非静态函数成员都为类所有,对象中并不存在函数的拷贝(每个对象所占用的存储空间只是该对象的数据成员所占用的存储空间,但是在逻辑上函数和数据是一起被封装进对象的)。静态成员函数和非静态成员函数的根本区别在于有无this指针。非静态函数由对象名.或者对象指针->调用,调用时编译器会向函数传递this指针;静态成员函数则有类名::或者对象名.调用,没有this指针,不识别对象个体,经常用来操作类的静态数据成员。访问类的非静态成员要通过对象来实现。
内存角度分析:
类的静态成员(数据成员和函数成员)为类本身所有,在类加载的时候就会分配内存,可以通过类名直接访问;非静态成员(数据成员和函数成员)属于类的实例所有,所以只有在创建类的实例的时候才会分配内存,并通过实例去访问。
注意:类的静态数据成员是静态存储,它是静态生存周期,必须进行初始化。
注意:静态数据成员的初始化在类体外进行,前面不加static以免与一般静态变量或者对象混淆。
静态成员函数访问非静态成员报错:
类的静态成员在类加载的时候就已经分配内存,而此时类的非静态成员尚未分配内存,访问内存中不存在的东西自然会出错。
/*类的静态成员(数据成员和函数成员)为类本身所有,在类加载的时候就会分配内存,可以通过类名直接访问;
非静态成员(数据成员和函数成员)属于类的实例所有,所以只有在创建类的实例的时候才会分配内存,并通过实例去访问。
注意:类的静态数据成员是静态存储,它是静态生存周期,必须进行初始化。
注意:静态数据成员的初始化在类体外进行,前面不加static以免与一般静态变量或者对象混淆。
*/
#include <iostream>
using namespace std;
class StaticTest
{
int a;
static int b; //静态成员变量可以认为是全局变量,随着类的出现而产生
public:
static void printTest(StaticTest t);//静态函数不能在类中定义,只能声明
StaticTest(int in)
{
a = in;
b++;
}
void nonStaticTest()//非静态成员函数必须在实例化后
{
cout << "This is non-static function" << endl;
cout << "location of this: " << this << endl; //这个实例化后的函数的地址
}
};
//静态成员函数必须要在类外定义
void StaticTest::printTest(StaticTest t)
{
cout<<"t.a: "<<t.a<<endl;
cout<<"StaticTest::b: "<<StaticTest::b<<endl;//静态变量可用::得到
cout<<"t.b: "<<t.b<<endl;
cout << "location of b: "<< &b << endl; //可以看到b的地址是不变的
}
//NOTE:静态成员变量必须要在类外和main()函数之前初始化,缺省时初始化为0。
int StaticTest::b; //默认值b=0
int main()
{
StaticTest a1(66);
StaticTest::printTest(a1);
StaticTest a2(88);
StaticTest::printTest(a2);
a1.nonStaticTest();//非静态成员函数必须要实例化后才行
a2.nonStaticTest();//可以看到函数的地址在变,而且好像还连续
return 0;
}
输出如下
t.a: 66
StaticTest::b: 1
t.b: 1
location of b: 0x557b464c8134
t.a: 88
StaticTest::b: 2
t.b: 2
location of b: 0x557b464c8134
This is non-static function
location of this: 0x7ffcb6a38c00
This is non-static function
location of this: 0x7ffcb6a38c04