从内存和对象的角度看C++类的静态…

提纲:
1,C++的内存分区:stack heap和静态存储区;
2,静态对象和实例对象;
3,使用规则;
4,应用场景;

一、C++的内存分区和对象模型
参考《C++Primer Plus》第9章“内存模型和名称空间”,C++中用“持续性、作用域和链接性”三个属性来表征其存储特性,包括变量和函数。C++的内存模型大致可以分为三块:堆(heap)、栈(stack)和静态存储区(可能有第四块存储区,用于存储函数,也有可能函数同全局变量一样,也是放在静态存储区)。其中,“堆”是一个动态存储区,存放运行时“new”出来的对象;“栈”存放局部变量、函数参数(实参)、函数调用时的函数地址等;“静态存储区”存放(静态)全局变量、静态局部变量,可能还有函数。
程序加载的时候,是先加载(静态)全局变量,在进入“main()函数”按程序执行加载或生成其他对象,故静态变量和普通变量不但存储区域不同,加载的时间也不同。(静态局部变量也是在 “main()函数”之前加载的 )参考《C++Primer Plus》P309,“由于静态变量的数目在程序运行期间是不变的,因此程序不需要使用特殊的装置(如栈)来管理它们。编译器将分配固定的内存块来存储所有的静态变量,这些变量在整个程序执行期间一直存在。另外,如果没有显式地初始化静态变量,编译器将把它设置为0”。
C++中无静态类,类必须在运行时进行实例化,即产生类的实例对象,该对象要么存储在栈,要么存储在堆中,虽然从语法上允许全局的类对象,但实际使用在很少见到(待分析其原因)。类的普通成员变量和成员函数都需要通过类的实例对象来调用,其中,在类的内通过隐含的“this指针”进行调用。而类的静态成员函数不能通过实例对象来调用,必须通过类名来调用,它的特性与全局函数相似,仅仅是被类限定了作用域而已。

二、使用规则
1,静态成员变量(以下简称静态成员)
1) static成员的所有者是类本身和对象,但是多有对象拥有一样的静态成员(静态成员变量是一个共享变量)。从而在定义对象是不能通过构造函数对其进行初始化,必须在类体外通过类名限定的形式进行初始化。(初始化的时候,不能加static,因为“static”关键词限定该变量的链接性为本文件)
2)静态成员不能在类定义里边初始化,只能在class body外初始化。
3)静态成员仍然遵循public,private,protected访问准则。
4)静态成员不可在类体内赋值,因为它是被所有类对象共享的,在一个对象内改变了,也会在其他对象中改变,造成混乱。为避免这种混乱,故限制它不可在类体内赋值。如果要改变静态成员,可以通过静态成员函数。

2,静态成员函数
1)静态成员函数没有this指针,它不能返回非静态成员,因为除了对象会调用它外,类本身也可以调用。
2) 出现在类体外的函数定义不能指定关键字static;
3)静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数
4)非静态成员函数可以任意地访问静态成员函数和静态数据成员;
5)静态成员函数不能直接访问非静态成员函数和非静态数据成员;可以通过对象名调用非静态成员函数,前提是要传入对象到该静态成员函数中。
6)由于没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度上会有少许的增长;
7)调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数, 当同一类的所有对象使用一个量时,对于这个共用的量,可以用静态数据成员变量,这个变量对于同一类的所有的对象都取相同的值。静态成员变量只能被静态成员函数调用。静态成员函数也是由同一类中的所有对象共用。只能调用静态成员变量和静态成员函数。

参考CSDN的博客: 静态成员变量和静态成员函数

你可能感兴趣的:(从内存和对象的角度看C++类的静态…)