C++构造函数与析构函数

目录

一、构造函数基础概念

1.概念

2.特点

3.分类

二、构造函数的调用

1.无参构造函数

2.有参构造函数

1)无默认参

 2)有默认参

3)有参构造函数的写法

三、拷贝构造函数

1.概念

2.调用

1)类对象拷贝举例

2)自定义拷贝构造函数

四、构造函数重载

1.概念

2.举例

五、析构函数基础概念

1.概念

2.特点

六、析构函数的调用


一、构造函数基础概念

1.概念

        一个类的数据成员多为私有的,在创建了一个类的对象时,要对它们进行初始化,必须用一个公有函数来进行,同时这个函数应该在且仅在定义对象时自动执行一次,称为构造函数。

2.特点

(1)函数名与类名相同,无函数返回类型。但并不是void,也不是无函数返回值,构造函数的返回值是构造函数所创建的对象。

(2)在程序运行时,当新的对象被建立,该对象所属的类构造函数自动被调用,在该对象生存期中只调用这一次

(3)构造函数可以重载。类中可以定义多个构造函数,它们由不同的参数表区分,系统在自动调用时按一般函数重载的规则选一个相匹配的执行。

(4)构造函数可以在类中定义,也可以在类中声明,在类外定义。

(5)如果类说明中没有给出构造函数,则C++编译器自动给出一个缺省的构造函数(只要我们定义了一个构造函数,系统就不会自动生成缺省的构造函数)。

3.分类

  • 按有无参数分为:无参构造函数、有参构造函数

二、构造函数的调用

1.无参构造函数

构造函数定义时没有参数,可在函数内对参数操作。

#include<iostream>
#include<time.h>
using namespace std;

class CDateTime
{
private:
	int year, month, day;
	int hour, min, sec;
public:
	CDateTime()  //无参构造函数
	{
		year = month = day = 1;
		hour = min = sec = 0;
	}
	void Print() const  //打印时间函数
	{
		printf("%04d/%02d/%02d-%02d:%02d:%02d\n", //用0补位  cout不能这样输出
			year, month, day, hour, min, sec);
	}
};
int main()
{
	CDateTime dt1; //通过CDateTime类实例化对象dt1
	//在此阶段调用构造函数,且仅调用一次
	dt1.Print();
	return 0;
}

运行结果:

0001/01/01-00:00:00

2.有参构造函数

1)无默认参

构造函数定义时有参数但未赋值,可在函数内对参数操作。在实例化对象时传入参数。

#include<iostream>
#include<time.h>
using namespace std;

class CDateTime
{
private:
	int year, month, day;
	int hour, min, sec;
public:
	CDateTime(const int y, const int m, const int d,
		const int h, const int n, const int s) //带参无默认值构造函数
	{
		year = y, month = m, day = d;
		hour = h, min = n, sec = s;
	}
	
	void Print() const  //打印时间函数
	{
		printf("%04d/%02d/%02d-%02d:%02d:%02d\n", //用0补位  cout不能这样输出
			year, month, day, hour, min, sec);
	}
};
int main()
{
	CDateTime dt1(2023,10,9,16,30,12); //通过CDateTime类实例化对象dt1
	//在此阶段调用构造函数,且仅调用一次
	dt1.Print();
	return 0;
}

运行结果:

2023/10/09-16:30:12

 2)有默认参

构造函数定义时有参数且已对参数(全部或部分)赋值。在实例化时传入参数,则传入的参数优先;如果没有传入参数,则使用默认的参数值。

#include<iostream>
#include<time.h>
using namespace std;

class CDateTime
{
private:
	int year, month, day;
public:
	CDateTime(int y = 2013, int m = 10, int d = 9);  //声明带参数的构造函数

	void Print() const //打印时间函数
	{
		printf("%04d/%02d/%02d\n", //用0补位  cout不能这样输出
			year, month, day);
	}
};

	CDateTime::CDateTime(int y, int m, int d)  //定义带参构造函数
	{
		year = y, month = m, day = d;
	}

int main()
{	
	CDateTime dt1;  
	CDateTime dt2(2023,10,2); //通过CDateTime类实例化对象dt2
	dt1.Print(); //默认参
	dt2.Print(); //传入参
	return 0;
}

运行结果:

2013/10/09
2023/10/02

 注意:(1)带默认参的函数一般先声明后定义再使用,声明和定义不能同时出现;

            (2)c++规定默认参数需写在参数列表的右边,例如:

CDateTime(int y , int m = 10, int d = 9);
CDateTime(int y , int m, int d = 9);

3)有参构造函数的写法

对于内置类型,以下两种写法等价:

若无默认参:

1.
CDateTime(int y, int m, int d)
{
	year = y, month = m, day = d;
}

2.
CDateTime(int y, int m, int d) :year(y), month(m), day(d) { }

 若有默认参,第2种写法为:

CDateTime(int y=2001, int m=5, int d=24):year(y),month(m),day(d){ }

三、拷贝构造函数

1.概念

 同一个类的对象在内存中有完全相同的结构,在建立对象时可用同一类的另一个对象来初始化该对象的存储空间,这时所用的构造函数称为拷贝构造函数。简单的说,就是旧对象初始化新对象

特点:在类中如果没有显式给出拷贝构造函数时,则C++编译器会自动给出一个缺省的拷贝构造函数。如果有程序设计者定义的构造函数(包括拷贝构造函数),则按函数重载的规律,调用合适的构造函数。

2.调用

1)类对象拷贝举例

#include<iostream>
#include<time.h>
using namespace std;

class CDateTime
{
private:
	int year, month, day;
public:

	//无默认参构造函数
	CDateTime(int y, int m, int d) :year(y), month(m), day(d) { }

	void Print() const //打印时间函数
	{
		printf("%04d/%02d/%02d\n", //用0补位  cout不能这样输出
			year, month, day);
	}
};


int main()
{	
	CDateTime dt2(2023,10,2); 
	CDateTime dt3 = dt2;
	dt3.Print();
	return 0;
}

 运行结果:

2023/10/02

        由上述例子我们可以看到,该程序为对象 dt3 分配了内存并拷贝了对象 dt2 的数据,这个过程并非普通的赋值,而是由拷贝构造函数完成的。

        在这个例子中,我们并没有定义拷贝构造函数,编译器给我们自动产生一个拷贝构造函数,即“默认拷贝构造函数”。

2)自定义拷贝构造函数

下面我们来看以下拷贝构造函数的工作原理。

#include<iostream>
#include<time.h>
using namespace std;

class CDateTime
{
private:
	int year, month, day;
public:

	//无默认参构造函数
	CDateTime(int y, int m, int d) :year(y), month(m), day(d) { }

    //自定义拷贝函数
	CDateTime(const CDateTime &n) 
	{
		year = n.year, month = n.month, day = n.day;
	}

	void Print() const //打印时间函数
	{
		printf("%04d/%02d/%02d\n", //用0补位  cout不能这样输出
			year, month, day);
	}
};


int main()
{	
	CDateTime dt2(2023,10,2); 
	CDateTime dt3(dt2);  //CDateTime dt3 = dt2;
	dt2.Print();
	dt3.Print();
	return 0;
}

运行结果:

2023/10/02

2023/10/02

例子详解:

CDateTime(const CDateTime &n) {...}

CDateTime dt3(dt2); // //CDateTime dt3 = dt2;

 在此处,n 是一个引用类型,前面加 const 表示该引用是个常引用,即被引用的值不能被修改。括号内可理解为 CDateTime n=dt2。因此,这里引用了 CDateTime 类的对象 dt2 ,拷贝了 dt2 的数据,即拷贝构造函数。

四、构造函数重载

1.概念

与普通函数重载相同,构造函数具有相同的名字,但参数列表不同,且无返回类型。

  • 参数列表不同:参数顺序或者参数类型不同。

2.举例

#include<iostream>
#include<time.h>
using namespace std;

class Rectangle  //定义一个矩形类
{
public:
	Rectangle()	//定义无参构造函数
		{
			width = 10;
			length = 20;
		} 

	Rectangle(int w ,int l) :width(w), length(l) {} //定义有参构造函数

	int area()  //定义计算面积的成员函数
	{
	return (width * length);
	}

private:
	int width;  //宽
	int length; //长
};

int main()
{
	Rectangle rec1(20, 30);
	cout << "The area of rec1 is:" << rec1.area() << endl; //600
	Rectangle rec2;
	cout << "The area of rec2 is:" << rec2.area() << endl; //200
	system("pause");
	return 0;
}

 运行结果:

The area of rec1 is:600
The area of rec2 is:200

 对象rec1:给出两个实参,系统匹配对应的有两个形参的构造函数,因此矩形的宽为20,长为30,面积为600。

对象rec2:没有给出参数,系统匹配对应的无参构造函数,因此矩形的宽为10,长为20,面积为200。

五、析构函数基础概念

1.概念

        当定义一个对象时,C++自动调用构造函数建立该对象并进行初始化,那么当一个对象的生存周期结束时,C++也会自动调用一个函数注销该对象并进行善后工作,这个特殊的成员函数即析构函数。

2.特点

(1)析构函数名与类名相同,但在前面加上字符‘~’,如 : ~CDateTime(

(2)析构函数名无函数返回类型,与析构函数相同,但析构函数不带任何参数

(3)一个类中只有一个析构函数。

(4)当创建的对象注销时,系统自动调用析构函数。

(5)如果类说明中没有给出析构函数,C++编译器会自动给出一个缺省的析构函数。

        如: ~类型名称( {}

六、析构函数的调用

#include<iostream>
#include<time.h>
using namespace std;

class CDateTime
{
private:
	int year, month, day;
public:
	
    //有默认参构造函数
	CDateTime(int y=2001, int m=5, int d=24):year(y),month(m),day(d){ }

    //析构函数
	~CDateTime()
	{
		cout << "Destroy CDateTime " << endl;
	}

	void Print() const //打印时间函数
	{
		printf("%04d/%02d/%02d\n", //用0补位  cout不能这样输出
			year, month, day);
	}
};

int main()
{	
	CDateTime dt2(2023,10,2); //通过CDateTime类实例化对象dt1
	dt2.Print();
	return 0;
}

运行结果:

2023/10/02
Destroy CDateTime

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值