对象的使用(2)

#复习:

        static成员独立于类对象而存在,也就是说它不属于某个对象的成员,它能被全体对象所共享。

        上节课中统计类类型对象的个数,用static成员来实现。

非static成员它属于类对象,每个对象都有一份拷贝,无法达到共享的目的。

        static成员函数没有this指针,它不能访问非static成员,也不能调用非static成员函数。

        static成员函数使用类名::Functionname()完成访问,如:A::staticFun();

#include <iostream>
using namespace std;

class Date
{
public:
	Date(int year) :year_(year)
	{
	}

	static bool IsleapYear(int year)
	{
		return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
	}
	bool IsleapYear()
	{
		return (year_ % 4 == 0 && year_ % 100 != 0) || (year_ % 400 == 0);
	}
private:
	int year_;

};
int main(void)
{
	Date d(2012);
	cout << d.IsleapYear() << endl;
	Date d2(2010);  //只是想判定某一年是否是瑞年,不想创建对象,使用静态成员函数实现。
	cout << d2.IsleapYear() << endl;
	cout << Date::IsleapYear(2010) << endl; //这里使用静态成员函数,不用创建对象。

	return 0;
}

本节内容:

1)四种对象的作用域与生存期

2)static用法总结

1)四种对象的作用域与生存期

        栈对象:隐含调用构造函数(程序中没有显示调用)

        堆对象:隐含调用构造函数(程序中没有显示调用)

        全局对象、静态全局对象:

                全局对象的构造先于main函数

                已初始化的全局变量或静态全局对象存储于.data段中

                未初始化的全局变量或静态全局存储于.bss段中

        静态局部对象

                已初始化的静态局部变量存储于.data段中

                未初始化的静态局部变量存储于.bss段中

#include <iostream>
using namespace std;

class Test
{
public:
	Test(int n):n_(n)
	{
		cout << "Test..." << n_ << endl;
	}

	~Test()
	{
		cout << "~Test "<< n_ << " ...." << endl;
	}

private:
	int n_;
};

int n;			//未初始化的全局变量等于0     n存储于.bss段中    bss = block started by symbol
int n2  = 100;	//已初始化的全局变量,初始值等于100  n2存储于.data段中
Test g(100);   //全局对象的构造先于main函数
static Test g2(200);

int main(void)
{
	cout << "Eentering main..." << endl;
	cout << n << endl;  
	Test t(10); //栈上创建的对象,在函数块中有效(生命周期),在生存期结束的时候自动释放。
	{
		Test t(20);
	}
	{
		Test* t3 = new Test(30);  //堆上创建的对象要显式释放(delete)
		delete t3;				//即使作用域结束,如果不显式调用delete,t3对象也不会释放。因此作用域与生存期不等同。
	}
	{
		static int n3;  //n3存储于.bss段中。(编译器初始化)
		static int n4 = 100;//n4存储于.data段中。(编译器初始化)

		static Test t4(333); //t4对象运行期初始化 .data段中
	}
	cout << "Exiting main..." << endl;
	
	return 0;
}
/*
输出结果:
Test...100
Test...200
Eentering main...
0
Test...10
Test...20
~Test 20 ....
Test...30
~Test 30 ....
Test...333
Exiting main...
~Test 10 ....
~Test 333 ....
~Test 200 ....
~Test 100 ....
*/

 

2)static用法总结

1、(C中)用于函数内部修饰变量,即函数内的静态变量。这种变量的生存期长于该函数,使得函数具有一定的”状态“。使用静态变量的函数一般是不可重入的。也不是安全线程。比如strtok(3).

void foo()
{
	static int n = 100;  //函数调用完后,变量n还是存在的。例如第一次进入函数n =100,再次进入不会再分配空间了,还是100
	n = 200;  //当我们把n改为200,x下次调用仍是200.n变量是有状态的,这种函数是不可重入函数,不是线程安全的函数。

}

2、(C中)用在文件级别(函数体之外),修饰变量或函数,表示该变量或者函数只在本文件可见,其它文件看不到也访问不到该变量或函数。专业的说法叫”具有internal linkage“(简言之:不暴露给别的translation unit).

C语言中者两种用法很明确,一般也不容易混淆。

//假如
a.c中有static int n = 100;
b.c中有static  int n = 100;//只在本文件可见,两文件中两者是可同时存在的,b.c看不到a.c中的n变量,a.c看不到b.c中的n变量

//如果a.c和b.c想共用同一个变量
a.c
int n = 100;
b.c
extern int n;  //这种变量称为external linlage 外部联动 
				//全局变量必须在.c文件中定义,不要在.h文件中定义。
					//如果在.h中定义全局变量,会报重复定义错误,如:x.h  中定义  int n = 100;  a.c 中包含头文件.h,这样会有一个int n = 100,同理b.c中也有一个int n =100;重复定义。

由于C++中引入了类,在保持于C语言兼容的同时,static关键字又有了两种新用法:

        3、用于修饰类的数据成员,即所谓”静态成员“。这种数据成员是每个instance有一份。

        4、用于修饰class的成员函数,即所谓”静态成员函数“。这种成员函数只能访问静态成员和其它静态成员函数,不能访问非静态成员和非静态成员函数。因为没有this指针。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值