c++类——构造函数

如有兴趣了解更多请关注我的个人博客https://07xiaohei.com/

(一)概念:

创建类的对象的时候,编译系统需要对象分配内存空间,完成数据成员的初始化工作并请求其他资源,此时,编译系统自动调用构造函数来完成这些工作。

因此,构造函数是在创建类的对象时使用,它的核心作用是初始化对象的数据成员分配内存

(二)原型和特点:

构造函数的原型为:**类名::类名(参数表):初始化列表 { 构造函数体 }

​ ——所有倾斜内容表示在构造函数中此内容可选,不是必要的。

​ ——参数表即为所有的传入形参

​ ——初始化列表结构为:数据成员名(某形参名),数据成员名(某形参名)…

​ ——构造函数体可执行相关操作可为cout<<某些信息,对数据成员的某些操作等等。

构造函数的特点:

  1. 名字与类名相同,允许设定参数,但是不允许设置返回值(包括void)。

  2. 构造函数是编译系统在实例化一个对象时自动执行的,不需要手动调用(当然也可以主动手动调用)。调用后会对对象的数据成员进行初始化。

    定义自己的无参构造函数实际上是有用构造函数

  3. 构造函数可以重载,但是对象的实例化只会使用其中的一个构造函数(参数类型和个数能够最佳匹配),且实例化后不会再次执行构造函数,另外,重载构造函数后不允许出现二义性情况。

    • 重载构造函数具有不同的参数表和相同的名称

    • 根据传参个数决定调用哪个构造函数

    • 创建对象时要传参数让编译器明确知道调用哪个构造函数

  4. 在未定义构造函数时,编译系统生成一个无用的默认构造函数,无用的默认构造函数不含参数,不做任何初始化工作

    一旦定义了自己的构造函数,系统不会自己生成无用的默认的无参构造函数,但是仍然可以自己指定系统生成无用默认无参构造函数。

(三)分类:

  1. 默认构造函数,又名缺省构造函数,分为有用和无用两种,是不需要显式指定实参的构造函数——即原型为无参构造函数。
  2. 初始化构造函数——有参数。
  3. 复制(拷贝构造函数(不显式指定时有默认的复制构造函数)。
  4. 转换构造函数

(四)基本用法:

1.默认构造函数:

形式:

  1. 类名() =default;”的形式或者不存在任何构造函数——指定无用默认构造函数。

  2. "类名(){ 函数体 }"的形式——指定有用默认构造函数

调用时,因默认构造参数不需要形参,直接声明类的对象即可(切记不要在后面跟“()”!)。

代码如下:

#include <iostream>
using namespace std;
class Time
{
private:
	int hour;  
	int minute;
	int sec;
public:
    //此时状态为无构造参数,编译系统自动生成无用构造参数
	//Time() = default; 仅去掉本行注释仍为无用构造参数
	//Time() {hour=0;minute=0;sec=0;} 仅去掉本行注释为有用构造参数,可对三个数初始化为0
	//上两行注释不能同时去掉,否则产生二义性。
	void set_time()
	{
		cin >> hour >> minute >> sec;
		return;
	}
	void show_time()
	{
		cout << hour << ":" << minute << ":" << sec << endl;
	}

};
int main()
{
	Time t1; //不能加"()"
	t1.set_time(); 
	t1.show_time();  
	return 0;
}
2.带参构造函数:

形式:类名:构造函数名(参数表):初始化列表 { 构造函数体 }

如果数据成员中有数组,要在构造函数体中用语句对其进行赋值,不能用初始化列表进行初始化。

以其他类作为数据成员时,需要在初始化列表进行初始化。初始化列表需要首先调用成员类的构造函数,再初始化自身的数据成员。

通常带参构造函数需要重载。

代码如下:

#include <iostream>
using namespace std;
class Time
{
private:
	int hour;  
	int minute;
	int sec;
public:
	//Time() = default;
	Time() { hour = minute = sec = 0; }
	Time(int i1, int i2, int i3) :hour(i1), minute(i2), sec(i3) {}//初始化列表方法
	//Time(int i1, int i2, int i3) { hour = i1; minute = i2; sec = i3; }//构造函数体方法
	Time(int h) :hour(h) { minute = sec = 0; }//重载构造函数1,实际上是转换构造函数
	Time(int h, int m) :hour(h), minute(m) { sec = 0; }//重载构造函数2
	//Time(int i1=0,int i2=0,int i3=0) :hour(i1), minute(i2), sec(i3) {}//含默认参数的构造函数,但要注意如果三个数均含默认参数,则会导致与默认构造参数产生二义性,只能保留一个。
	void set_time()
	{
		cin >> hour >> minute >> sec;
		return;
	}
	void show_time()
	{
		cout << hour << ":" << minute << ":" << sec << endl;
	}

};
int main()
{
	Time t1(1,2,3);
	//Time t2;
    //Time t3(1,2);
    //Time t4(1);
	t1.set_time(); 
	t1.show_time();  
	return 0;
}
3.复制(拷贝)构造函数:

此内容较多,单开一篇博客,详见c++类——复制构造函数

4.转换构造函数:

形式:类名:构造函数名(单一参数):初始化列表 { 构造函数体 }

转换构造函数用于将其他类型的变量,隐式转换为本类对象。

传入的单一参数不能是本类的const引用,否则为复制构造函数。

转换构造函数可以与运算符重载配合使用(运算符重载详见c++类——运算符重载)。

代码如下:

#include <iostream>
using namespace std;
class Time
{
private:
	int hour;  
	int minute;
	int sec;
public:
	//Time() = default;
	Time() { hour = minute = sec = 0; }
	Time(int i1, int i2, int i3) :hour(i1), minute(i2), sec(i3) {}
	Time(int h) :hour(h) { minute = sec = 0; }//转换构造函数

	void set_time()
	{
		cin >> hour >> minute >> sec;
		return;
	}
	void show_time()
	{
		cout << hour << ":" << minute << ":" << sec << endl;
	}
	Time operator+(const Time& temp) 
	{
		return Time(this->hour + temp.hour, this->minute + temp.minute, this->sec + temp.sec);
	}
};
int main()
{
	Time t1=4; //此处4先被编译器用转换构造函数隐式转换为Time类的匿名变量,再复制给t1(调用了默认复制函数和转换构造函数)。
	t1.show_time();
	t1 = t1 + 5; //此处发生的是5先被编译器用转换构造函数隐式转换为Time类的匿名变量,再和t1通过运算符重载的函数进行相加。
	t1.show_time();
	return 0;
}

附:关键字explicit:

因为隐式类型转换往往会导致工程中出现一些奇奇怪怪的bug,所以,c++中定义了关键字explicit来杜绝转换构造函数的隐式类型转换。

关键字explicit只能用于修饰转换构造函数(也就是只含一个参数的类构造函数)或参数表中仅有一个没有默认参数的带参构造函数(等效于转换构造函数),其作用是表明该转换构造函数是显式的,而不是隐式的。

如果想指定默认情况为隐式的声明,可在前面指定关键字implicit。(不常用)

代码如下:

#include <iostream>
using namespace std;
class Time
{
private:
	int hour;  
	int minute;
	int sec;
public:
	//Time() = default;
	Time() { hour = minute = sec = 0; }
	Time(int i1, int i2, int i3) :hour(i1), minute(i2), sec(i3) {}
	explicit Time(int h) :hour(h) { minute = sec = 0; }//转换构造函数

	void set_time()
	{
		cin >> hour >> minute >> sec;
		return;
	}
	void show_time()
	{
		cout << hour << ":" << minute << ":" << sec << endl;
	}
	Time operator+(const Time& temp) 
	{
		return Time(this->hour + temp.hour, this->minute + temp.minute, this->sec + temp.sec);
	}
};
int main()
{
	Time t1= static_cast<Time>(4);//必须显式指定,不会隐式转换。
	//t1.set_time(); 
	t1.show_time();
	t1 = t1 + 5;// 不会发生隐式转换,运算符重载函数发生错误。
	t1.show_time();
	return 0;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C++ 默认构造函数是在没有显式定义构造函数的情况下自动生成的特殊成员函数。它通常用于在创建对象时进行初始化操作。默认构造函数无参数,不接受任何实参。当我们通过调用构造函数来创建对象时,如果没有提供实参,则编译器会自动调用默认构造函数。 默认构造函数的作用是确保对象的所有成员变量都被正确初始化。例如,如果一个有一个int型的成员变量,那么在默认构造函数中,可以将该成员变量初始化为0。如果没有默认构造函数,当我们创建对象时,该成员变量可能会未被初始化,导致程序运行时出现意外结果。 另一个重要的地方是,当我们定义了的其他构造函数时(比如有参数的构造函数),默认构造函数依然会被生成。这是因为在某些情况下,我们可能只想使用默认构造函数来创建对象,而不希望传递实参。此时,默认构造函数就能满足需求。当我们重载构造函数时,可以使用默认参数来实现默认构造函数的功能。 需要注意的是,默认构造函数在一些特殊情况下可能不会被生成。例如,如果我们显式定义了有参数的构造函数,但没有提供默认构造函数,那么编译器将不会自动生成默认构造函数,这意味着我们不能再使用无参的方式来创建对象。 总之,理解C++默认构造函数的作用和用法对于编写高质量的代码至关重要。它可以帮助我们确保对象的正确初始化,并且在一些特殊情况下可以提供方便的使用方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

xiaohei07

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

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

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

打赏作者

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

抵扣说明:

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

余额充值