十二、对象的使用(一) static成员变量、static成员函数、类/对象大小计算

一、C语言的static变量和static函数

      首先回顾一下C语言的static变量用法。

#include <iostream>
using namespace std;
//用static修饰变量使变量的状态保留
//因为静态变量只能被初始化一次
void GetStatic()
{
	int a = 10;
	//b只初始化一次
	static int b = 10;
	printf("a:%d b:%d \n", a, b);
	a++;
	b++;
}
int main()
{
	GetStatic();
	GetStatic();
}
打印结果:

a:10 b:10
a:10 b:11

C语言的静态函数是修饰函数的作用域,static修饰的函数具有文件作用局,无法通过extern在另一个文件访问被static修饰的函数

二、C++static成员变量定义

static成员的定义:static成员需要在类体内声明类定义体外进行初始化与定义

特殊整型static const成员: 整型static const成员可以在类定义体中初始化,该成员可以不在类体外进行定义

三、C++的static成员变量使用

      对于特定类型的全体对象而言,有时候可能需要访问一个全局的变量。比如说统计某种类型对象已创建的数量。如果我们用全局变量会破坏数据的封装,一般的用户代码都可以修改这个全局变量,这时我们可以用类的静态成员来解决这个问题。非static数据成员存在于类类型的每个对象中,static数据成员独立该类的任意对象存在,它是与类关联的对象,不与类对象关联。也就是说,对于static变量来说,所有的对象共享这个变量。
例子如下:
#include <iostream>
using namespace std;
class X
{
public:
	char ch;
	int static s;  //这里是static s的声明,s必须在类外定义!!
};
int X::s = 0;//s的定义
int main()
{
	X a,b;
	a.s = a.s+10; //对a的s加10
	cout<<b.s<<endl;//打印b的s
}
结果:10,可见对象是共享static成员变量的。对于这个例子,我们可以这样理解它的内存模型:

static成员优点如下:
  • static成员的名字是在类的作用域中,因此可以避免与其它类成员或全局对象名字冲突。
  • 可以实施封装,static成员可以是私有的,而全局对象不可以
  • 阅读程序容易看出static成员与某个类相关联,这种可见性可以清晰地反映程序员的意图,增加代码可读性。
四、C++static成员函数
  • static成员函数没有this指针(因为static成员函数属于类,不属于某个对象)
  • 非静态成员函数可以访问静态成员(因为static成员函数属于类,任何此类对象都可以使用
  • 静态成员函数不可以访问非静态成员(非静态成员函数属于具体某个对象,必须通过对象调用成员函数,但是static成员函数不存在对象,所以无法调用非静态函数
例子如下:
#include <iostream>
using namespace std;
class Test
{
public:
	Test(int y) : y_(y){}
	~Test(){}
	void TestFun()
	{
		cout<<"x="<<x_<<endl;	//OK,非静态成员函数可以访问静态成员
		TestStaticFun();
	}
	static void TestStaticFun()
	{
		cout<<"TestStaticFun ..."<<endl;
		//TestFun();		Error,静态成员函数不能调用非静态成员函数
		//cout<<"y="<<y_<<endl;		Error,静态成员函数不能访问非静态成员
	}
	static int x_;		// 静态成员的引用性说明
	int y_;
};
int Test::x_ = 100;		// 静态成员的定义性说明
int main(void)
{
	cout<<sizeof(Test)<<endl;
}
打印结果:4。因为static成员变量放在全局变量区,不占用类存储空间。
五、类、对象大小计算
  • 类大小计算遵循前面学过的结构体对齐原则
  • 类的大小与数据成员有关与成员函数无关
  • 类的大小与静态数据成员无关
  • 虚函数对类的大小的影响
  • 虚继承对类的大小的影响
C++成员函数放在存储于代码段中,通过this指针区分不同对象的访问,不占用对象的存储空间。静态成员变量存储于全局数据区中,也 不占用对象的存储空间。虚继承或者虚函数会跟对象增加一个虚基表指针和虚表指针,影响对象的内存布局,具体如何影响的,留到下片文章吧。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值