C++学习第三课 第一节 构造函数

构造函数

C++中的类和对象对应了C语言中的结构体和结构体变量。
在C语言中,我们应该养成变量初始化的习惯。
以下我们无法从语法上检查出,不初始化的错误:

struct tagClock{
	int iHour;
	int iMin;
	int iSec; 5 
	};
int main(int argc, char* argv[])
{
	tagClock timer1;	
	printf("%02d:%02d:%02d\r\m", timer1.iHour,
	timer1.iMin,
	timer1.iSec);
	return 0;
}

C++中为了可以更方便地初始化对象,提出了构造函数的概念。

构造函数概念

构造函数是帮助我们自动初始化对象的函数。

构造函数的原理

  • 定义类时,定义了构造函数
  • 构造函数内部,可以对变量进行操作(因为构造函数也是一个方法,有this指针)
  • 编译器,会在变量生命周期的开始,自动调用这个类的构造函数

构造函数的语法

构造函数也是一个类中的方法。所以它的定义语法,与普通类方法非常相似。要声明一个类的构造函数,只需要在类中写:

类名(参数列表)
{ 
	函数实现体
}

实例:


	struct tagClock{
		int iHour;
		int iMin;
		int iSec;
	
	tagClock(){
		iHour = 0;
		iMin = 0;
		iSec = 0;
	}
	
	tagClock(int hour, int min, int sec){
		iHour = hour;
		iMin = min;
		iSec = sec;
	}
	
	void Show(){
		printf("%02d:%02d:%02d\r\n", iHour,
		iMin,
		iSec);
		}
	};
	
	
	
	int main(int argc, char* argv[])
	{
		tagClock timer1(20, 12, 5);
		tagClock timer2;
	
		timer1.Show();
		timer2.Show();
		return 0;
	}

总结:

  • 构造函数的名字必须与类名相同
  • 构造函数不能有返回值
  • 构造函数是可以重载的
  • 构造函数不可以被显式调用,如以下方法调用,无法通过编译:
tagClock timer1;
timer1.tagClock(); //编译不通过,不能显式调用

并且,为了照顾大家的写法习惯,C++中初始化变量时,以下的写法,其实也是调用构造函数:

tagClock timer1 = { 20, 12, 5 };
//等价于tagClock timer1(20, 12, 5);

拷贝构造及其意义

在C语言中,我们可以将同类型的,一个结构体变量,赋值给另外一个结构体变量。
如:

  struct tagClock{
	int iHour;
	int iMin;
	int iSec;
	};
	
	int main(int argc, char* argv[])
	{
	struct tagClock timer1 = { 20, 12, 5 };
	struct tagClock timer2 = timer1;
	return 0;

以上的赋值过程,其实相当于:

memcpy(&timer2, &timer1, sizeof(struct tagClock));

以上,虽然方便,但是灵活度不够。所以,C++提供了拷贝构造。它是一种较为特殊的构造,其触发的条件有两条:

  • 发生在对象生命周期开始
  • 拷贝构造的参数,必须是同类型的类的引用比如以下实例:
struct tagClock
{
	int iHour;
	int iMin;
	int iSec;

	tagClock(){
		iHour = 0;
		iMin = 0;
		iSec = 0;
	}

	tagClock(int argHour, int argMin, int argSec){
		iHour = argHour;
		iMin = argMin;
		iSec = argSec;
	}
	tagClock(tagClock& otherClock){//拷贝构造
		printf("我是拷贝构造\r\n");
		iHour = otherClock.iHour+1;
		iMin = otherClock.iMin;
		iSec = otherClock.iSec;
	

}
	
	void Show(){
			printf("%02d:%02d:%02d\r\n", iHour,
			iMin,
			iSec);
		}
	};
	
	int main(int argc, char* argv[])
	{
		struct tagClock timer1 = { 20, 12, 5 };
		struct tagClock timer2(timer1);
		
		timer1.Show();
		timer2.Show();

	return 0;
}

如果我们不实现拷贝构造,则编译器会自动生成一个拷贝构造,其作业等同于memcpy(其实是为了完全兼容C)

拷贝构造的其它发生时机

  1. 把对象作为参数进行值传递


	void Fun(tagClock myclock)
	{
		myclock.Show();
	}
	
	int main(int argc, char* argv[])
	{

		struct tagClock timer1 = { 20, 12, 5 };
		struct tagClock timer2(timer1);		
		timer1.Show();
		timer2.Show();
		
		Fun(timer1);
		
		return 0;
	}	
  1. 局部变量对象作为返回值返回时
	
  tagClock Fun()
	{
	tagClock timer1(10, 10, 0);
	return timer1;
	}
	
	int main(int argc, char* argv[])
	{
	printf("%d", Fun().iHour);
	tagClock timer2 = Fun();
	return 0;
	}

注意将对象的引用或者指针作为参数传递,不会发生拷贝构造。如:

	
 void Fun(tagClock& timer)
	{
		timer.Show();
	}
	
	int main(int argc, char* argv[])
	{
		tagClock timer(10, 10, 10);
		Fun(timer);
		return 0;
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值