构造与析构

 文章目录


前言

类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。

类的数据成员多为私有的,要对它们进初始化,必须用一个公有函数来进行。同时这个函数应该在且仅在定义对象时自动执行一次。这个函数就是构造函数。它由系统自动调动,用户不可以调动。

当一个对象被定义时,C++自动调用构造函数对该对象进行初始化,那么当一个对象的生命周期结束时,C++也会自动调用一个函数进行扫尾工作,这个特殊的成员函数就是析构函数。 


一、构造函数的作用和用法

作用:初始化

特点:

(1)函数名用类名,没有返回值

(2)访问权限必为public

(3)系统自动调用在定义对象时

(4)系统默认分配构造函数,没有函数体,默认参数,不能和函数重载一起用,否则冲突!

下面是一个时间的类的代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Time
{
public:
	//无参构造函数
	Time()
	{
		hour = 0;
		minute = 0;
		second = 0;
	}
	//有参构造函数
	Time(int h,int m,int s)
	{
		hour = h;
		minute = m;
		second = s;
	}
	//用于设置时间的函数
	void setTime(int h, int m, int s)
	{
		hour = h;
		minute = m;
		second = s;
	}
	//用于显示时间的函数
	void showTime()
	{
		cout << hour << " " << minute << " " << second << endl;
	}
private:
	int hour;
	int minute;
	int second;
};
int main()
{
	Time t1, t2(1, 2, 3);
	t1.showTime();
	t2.showTime();
	return 0;
}

运行结果如下: 

 此构造函数重载了两次。

以下为默认函数,相当于无参构造函数与有参构造函数相结合,且两者只能二选一。

Time(int h=10, int m=10, int s=10)
{
	hour = h;
	minute = m;
	second = s;
}

以下是参数初始化列表相当于有参构造函数,与其二选一使用。

 

 

 

二、析构函数

作用:对象撤销前的清理工作

特点:

(1)函数名用~加类名(){}

(2)没有返回值类型,没有参数

(3)调用:在对象撤销时类外系统自动调用

析构函数代码如下:

~Time()
	{
		cout << "deconstructor called" << endl;
	}

 其中“ deconstructor called”仅用于显示析构是否成功。

将此析构函数加入到上面时间类的代码

析构的顺序为:

1.调用析构函数

2.撤销t2,t1

3.输出两遍 

简单的总结与训练

顺序为先构造后虚构

下面我们来尝试一个简单的题目:

首先定义一个学生类要求数据包含学号,姓名,性别

函数包括构造函数(同时输出constructor called),显示函数,析构函数 (同时输出deconstructor called)

参考答案如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<string>
using namespace std;
class Student
{
public:
	Student(int m, string n, char s)
	{
		num = m;
		name = n;
		sex = s;
		cout << "constructor called" << endl;
	}
	void display()
	{
		cout << "num:" << num << endl;
		cout << "name:" << name << endl;
		cout << "sex:" << sex << endl;
	}
	~Student()
	{
		cout << "deconstructor called" << endl;
	}
private:
	int num;
	string name;
	char sex;
};
int main()
{
	Student stu1(1001, "Liming", 'm');
	stu1.display();
	Student stu2(1002, "Wangfang", 'f');
	stu2.display();
	return 0;
}

 运行结果为: 

由此推断执行顺序为:stu1构造->stu1.display->stu2构造->stu2.display->stu2析构->stu1析构 

三、拷贝构造函数

上面的时间的类代码中假设我们想将t2的数据赋给t1,我们用Time t1(t2);将t2赋给t1可行吗?

答案必然是否定的,因为“=”是库函数的一种运算函数,只能对系统的内置类型进行运算,那么我们该怎么做呢?

这时我们就可以利用 拷贝构造函数

作用:用一个已经初始化过的对象给新的对象初始化

函数名:类名+新对象名+(已有对象)

此函数利用了this指针的概念,其实类的所有成员函数必有类作参数只是在写的时候省略了  

例如上面Time中的函数

//用于显示时间的函数
	void showTime()
	{
		cout << hour << " " << minute << " " << second << endl;
	}

它的含义其实是:

void showTime(Time * this)
	{
		cout <<this->hour << " " << this->minute << " " << this->second << endl;
	}

 即类的成员函数的第一个参数都是当前类的对象的指针,即this指针。

当我们想写一个拷贝类的函数时,还是以Time为例,我们会写成

void copy(Time t1, Time t2)
	{
		t1.hour = t2.hour;
		t1.minute = t2.minute;
		t1.second = t2.second;
	}

但这种写法忽略了隐藏的指向当前类的对象的指针

正确写法应该为:

Time(const Time &t)
	{
		hour = t.hour;
		minute = t.minute;
		second = t.second;
	}

  总结
以上就是今天要讲的内容,本文仅仅简单地介绍了构造,析构,拷贝构造函数的使用。

让我们做一个小练习复习一下今天的内容:

定义一个复数类Complex,数据成员包含实部real 虚部img,成员函数包括构造函数,输出函数,求两个函数的和add(const Complex &c)

参考答案如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Complex
{
public:
	Complex(int r = 0, int i = 0)
	{
		real = r;
		img = i;
	}
	void display()
	{
		cout << "相加结果为:" << real << "+" << img << "i" << endl;
	}
	Complex add(const Complex &c)
	{
		Complex s;
		s.real = real + c.real;
		s.img = img + c.img;
		return s;
	}
private:
	int real;
	int img;
};
int main()
{
	Complex c1(2, 3);
	Complex c2(4, 5);
	Complex c3;
	c3 = c1.add(c2);
	c3.display();
	return 0;
}

最后一个小tips:注意调用时第一个参数写在外面,括号里从第二个参数开始写 

本篇文章就到这里了,祝大家成绩都能蒸蒸日上。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

巧克力小羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值