C++第八天

1.时钟程序(多文件)

Clock.h头文件

#ifndef _CLOCK_H_
#define _CLOCK_H_

struct Time{
	int hour;
	int minute;
	int second;
};
void set(Time* p,int h,int m,int s);
void tick(Time* p);
void show(Time* p);
void run(Time* p);
#endif

Clock.cpp实现文件

#include "Clock.h"
#include <iostream>
using namespace std;
#include <ctime>

void set(Time* p,int h,int m,int s)
{
	p->hour = h;
	p->minute = m;
	p->second = s;
}
void tick(Time* p)
{
	time_t t = time(NULL);
	while(time(NULL) == t){};
	if(++(p->second) >= 60)
	{
		p->second = 0;
		if(++(p->minute) >= 60)
		{
			p->minute = 0;
			if(++(p->hour) >= 24)
			{
				p->hour = 0;
			}
		}
	}
}
void show(Time* p)
{
	//回到行开头,覆盖上次时间,而不是在上次时间后面显示
	cout<<'\r';
	if(p->hour < 10)
	{
		//小于10表示只有一位数,前面补0
		cout<<0;
	}
	cout<<p->hour<<':';
	if(p->minute < 10)
	{
		cout<<0;
	}
	cout<<p->minute<<':';	
	if(p->second < 10)
	{
		cout<<0;
	}
	//cout输出到缓冲区,缓冲区man后显示在终端
	//flush表示立即显示
	cout<<p->second<<flush;
}
void run(Time* p)
{
	for(;;)
	{
		tick(p);
		show(p);
	}
}

main.cpp

#include "Clock.h"

int main()
{
	Time t;
	set(&t,10,45,50);
	run(&t);
}

执行结果:

root@host:/home/LinuxShare/004.c++/day08# g++ *.cpp
root@host:/home/LinuxShare/004.c++/day08# ./a.out
10:46:40

1.1.修改结构中变量名称

如果需要将Time结构中的变量名称做修改。

struct Time{
	int hour;
	int minute;
	int second;
};

修改为:

struct Time{
	int hour;
	int min; //原变量名:minute
	int sec; //原变量名:second
};

那么函数中的变量名称也需要随着更改。具体需要更改哪些函数呢?如果其他开发人员也使用到了Clock.h头文件,那么变更之处将不可控。

1.2.将函数放入结构中,变成结构的成员函数

这样更改的好处:
(1)成员变量修改时,可以明确需要修改的函数都是成员函数,两者同时修改即可;
(2)如果其他结构中也有同名函数,不冲突,不影响使用。
Clock.h

#ifndef _CLOCK_H_
#define _CLOCK_H_

struct Time{
	int hour;
	int min; //变量名修改
	int sec; //变量名修改
	void set(Time* p,int h,int m,int s);
	void tick(Time* p);
	void show(Time* p);
	void run(Time* p);
};
#endif

Clock.cpp

#include "Clock.h"
#include <iostream>
using namespace std;
#include <ctime>

//类型名::成员函数
void Time::set(Time* p,int h,int m,int s)
{
	p->hour = h;
	p->min = m; //变量名修改
	p->sec = s; //变量名修改
}
//类型名::成员函数
void Time::tick(Time* p)
{
	time_t t = time(NULL);
	while(time(NULL) == t){};
	if(++(p->sec) >= 60) //变量名修改
	{
		p->sec = 0; //变量名修改
		if(++(p->min) >= 60) //变量名修改
		{
			p->min = 0; //变量名修改
			if(++(p->hour) >= 24)
			{
				p->hour = 0;
			}
		}
	}
}
//类型名::成员函数
void Time::show(Time* p)
{
	cout<<'\r';
	if(p->hour < 10)
	{
		cout<<0;
	}
	cout<<p->hour<<':';
	if(p->min < 10) //变量名修改
	{
		cout<<0; 
	}
	cout<<p->min<<':';	//变量名修改
	if(p->sec < 10) //变量名修改
	{
		cout<<0; 
	}
	cout<<p->sec<<flush; //变量名修改
}
//类型名::成员函数
void Time::run(Time* p)
{
	for(;;)
	{
		tick(p);
		show(p);
	}
}

main.cpp

#include "Clock.h"

int main()
{
	Time t;
	t.set(&t,10,45,50); //变量.成员
	t.run(&t); //变量.成员
}

1.3.成员函数中的参数Time* p多余

在调用成员函数时,程序会自动把结构变量的地址传过来,可以通过this指针来使用这个地址,this是内部自动定义。
Clock.h

#ifndef _CLOCK_H_
#define _CLOCK_H_

struct Time{
	int hour;
	int min;
	int sec;
	void set(int h,int m,int s);
	void tick();
	void show();
	void run();
};
#endif

Clock.cpp

#include "Clock.h"
#include <iostream>
using namespace std;
#include <ctime>

//类型名::成员函数
void Time::set(int h,int m,int s)
{
	this->hour = h; //使用this
	this->min = m;  //使用this
	this->sec = s; //使用this
}
//类型名::成员函数
void Time::tick()
{
	time_t t = time(NULL);
	while(time(NULL) == t){};
	if(++(this->sec) >= 60) //使用this
	{
		this->sec = 0; //使用this
		if(++(this->min) >= 60)//使用this
		{
			this->min = 0; //使用this
			if(++(this->hour) >= 24) //使用this
			{
				this->hour = 0; //使用this
			}
		}
	}
}
//类型名::成员函数
void Time::show()
{
	cout<<'\r';
	if(this->hour < 10) //使用this
	{
		cout<<0;
	}
	cout<<this->hour<<':'; //使用this
	if(this->min < 10) //使用this
	{
		cout<<0; 
	}
	cout<<this->min<<':';	//使用this
	if(this->sec < 10) //使用this
	{
		cout<<0; 
	}
	cout<<this->sec<<flush; //使用this
}
//类型名::成员函数
void Time::run()
{
	for(;;)
	{
		tick();
		show();
	}
}

main.cpp

#include "Clock.h"

int main()
{
	Time t;
	t.set(10,45,50);
	t.run();
}

1.3.成员函数中的this->多余

成员函数使用当前变量的成员变量,this->可以不写。
Clock.cpp

#ifndef _CLOCK_H_
#define _CLOCK_H_

struct Time{
	int hour;
	int min;
	int sec;
	void set(int h,int m,int s);
	void tick();
	void show();
	void run();
};
#endif

Clock.cpp

#include "Clock.h"
#include <iostream>
using namespace std;
#include <ctime>

//类型名::成员函数
void Time::set(int h,int m,int s)
{
	hour = h; //去掉this
	min = m;  //去掉this
	sec = s; //去掉this
}
//类型名::成员函数
void Time::tick()
{
	time_t t = time(NULL);
	while(time(NULL) == t){};
	if(++(sec) >= 60) //去掉this
	{
		sec = 0; //去掉this
		if(++(min) >= 60)//去掉this
		{
			min = 0; //去掉this
			if(++(hour) >= 24) //去掉this
			{
				hour = 0; //去掉this
			}
		}
	}
}
//类型名::成员函数
void Time::show()
{
	cout<<'\r';
	if(hour < 10) //去掉this
	{
		cout<<0;
	}
	cout<<hour<<':'; //去掉this
	if(min < 10) //去掉this
	{
		cout<<0; 
	}
	cout<<min<<':';	//去掉this
	if(sec < 10) //去掉this
	{
		cout<<0; 
	}
	cout<<sec<<flush; //去掉this
}
//类型名::成员函数
void Time::run()
{
	for(;;)
	{
		tick();
		show();
	}
}

main.cpp

#include "Clock.h"

int main()
{
	Time t;
	t.set(10,45,50);
	t.run();
}

1.4.成员变量可以任意公开访问修改

修改main.cpp

#include "Clock.h"

int main()
{
	Time t;
	t.set(10,45,50);
	t.hour = 100; //在主函数访问Time机构体中成员并修改
	t.run();
}

执行结果:

e/LinuxShare/004.c++/day08#
root@host:/home/LinuxShare/004.c++/day08#
root@host:/home/LinuxShare/004.c++/day08#
root@host:/home/LinuxShare/0

2.类(结构体修改为类)

2.1.结构体stuct修改为类class

其他都不变,更改数据结构为类。

#ifndef _CLOCK_H_
#define _CLOCK_H_
//struct修改为Class
class Time{ 
	int hour;
	int min;
	int sec;
	void set(int h,int m,int s);
	void tick();
	void show();
	void run();
};
#endif

类中成员变量和成员函数,默认都是私有,在main.cpp直接访问,访问了私有变量,导致编译报错。

2.2.类实现时钟程序

Clock.h

#ifndef _CLOCK_H_
#define _CLOCK_H_

class Time{
private:
	int hour;
	int min;
	int sec;
public:
	void set(int h,int m,int s);
	void tick();
	void show();
	void run();
};
#endif

Clock.cpp

#include "Clock.h"
#include <iostream>
using namespace std;
#include <ctime>


void Time::set(int h,int m,int s)
{
	hour = h; 
	min = m;  
	sec = s; 
}

void Time::tick()
{
	time_t t = time(NULL);
	while(time(NULL) == t){};
	if(++(sec) >= 60) 
	{
		sec = 0; 
		if(++(min) >= 60)
		{
			min = 0; 
			if(++(hour) >= 24) 
			{
				hour = 0; 
			}
		}
	}
}

void Time::show()
{
	cout<<'\r';
	if(hour < 10) 
	{
		cout<<0;
	}
	cout<<hour<<':'; 
	if(min < 10) 
	{
		cout<<0; 
	}
	cout<<min<<':';	
	if(sec < 10) 
	{
		cout<<0; 
	}
	cout<<sec<<flush; 
}

void Time::run()
{
	for(;;)
	{
		tick();
		show();
	}
}

main.cpp

#include "Clock.h"

int main()
{
	Time t;
	t.set(10,45,50);
	t.run();
}

3.对象

对象:类型是“类”的变量。
对象初始化:创建对象时不能像初始化结构一样初始化(原因:private),需要使用构造函数初始化。

3.1.构造函数

构造函数(constructor):跟类名同名的函数称为构造函数,创建对象时构造函数自动被调用,是第一个被调用的成员函数,不用写返回类型(自动调用,即使有返回值也无法取到),常用于初始化成员变量。构造函数只能用于自动调用,一般不主动调用。创建一个对象,只调用一个构造函数(存在多个构造函数的情形),并且只调用一次构造函数。构造函数一般是public成员函数(原因:定义时需调用)。
构造函数传参数:在创建对象(类变量)时直接传参数。如果构造函数中没有形参则不需要传参数。
构造函数重载:一个类中可以存在多个构造函数,并且形参类型不同,构造函数调用时根据形参类型匹配调用。

3.2.初始化列表

初始化:在构造函数的函数头和函数体之间增加初始化信息,(:初始化列表,即冒号+初始化列表)。如果有多项需要初始化,用逗号隔开。常量可以初始化,不能赋值。
构造函数名后初始化时不能初始化数组和结构变量。

A():n(n),d(120.0)
{
  cout<<"call A()"<<this<<endl;
}

3.3.形参默认值

如果只想写一个构造函数,要求可以不传参数,可以传两个参数,也可以传三个参数。可通过使用形参默认值实现:在形参中增加默认值,在调用时如果只传一个参数默认传给第一个形参,传两个参数则传给第一个形参和第二个形参。----函数重载。

A(int n=0,d=0.0):n(n),d(120.0)
{
   cout<<"call A(int)"<<this<<endl;
}

函数重载过程中,如果两个同名函数,一个无形参,一个有形参但形参有默认值。当不传参数调用时编译器无法区分实际调用哪个函数,编译报错。

3.4.析构函数

析构函数(destructor):在对象被释放的时候自动调用。又名:解构函数、解构器、析构器。
构造函数在创建对象时被自动调用,所以也应为public,创建时可以传参数。但析构函数不是在创建时被调用,无法传参数,所以析构函数没有形参,无法重载。
全局变量,先创建后释放。要保证在main中可以使用,需要在进入main前被创建;为保证main中使用结束才释放,需要在main结束后被释放。
static:静态变量,生命周期被延长。只能被创建一次。

3.5.变量创建和释放顺序

#include <iostream>
using namespace std;

class A{
	int n;
public:
	A(int n=0):n(n)
	{
		cout<<this<<' '<<"A("<<n<<")"<<endl;
	}
	~A()
	{
		cout<<this<<' '<<"~A("<<n<<")"<<endl;
	}
};

void func()
{
	A a3(3);
	static A a4(4); //静态,声明周期被延长,释放被延迟
}
int main()
{
	func();
	A a1(1);
}
A a2(2); //全局,进入main函数前需创建

执行结果:

root@host:/home/LinuxShare/004.c++/day08# g++ main.cpp
root@host:/home/LinuxShare/004.c++/day08# ./a.out
0x55f741fd0138 A(2)
0x7ffef59b7534 A(3)
0x55f741fd0140 A(4)
0x7ffef59b7534 ~A(3)
0x7ffef59b7564 A(1)
0x7ffef59b7564 ~A(1)
0x55f741fd0140 ~A(4)
0x55f741fd0138 ~A(2)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值