默认成员函数:详解类的隐式操作

这篇具有很好参考价值的文章主要介绍了默认成员函数:详解类的隐式操作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

默认成员函数:详解类的隐式操作

一.类的默认成员函数

类的默认成员函数就是定义一个类后,类会自动生成的成员函数,若我们显示定义则类不会自动生成。

二.构造函数

在数据结构学习阶段我们手撕过栈、链表、队列等数据结构,当时我们是用C语言来实现的,每一种数据结构都有自己的初始化和销毁函数。这两个函数对数据结构的使用非常重要,但是我们又常常忘记使用,所以C++在类中设定了默认成员函数——构造函数,它的作用是初始化函数
他有以下的特征:

  1. 函数名与类名相同。
  2. 无返回值(连void都不用写
  3. 函数可以重载
  4. 若无显示定义则在类成员实例化的时候自动调用

还有以下特点要注意,这里我们使用经典的日期类作讲解:

class Date
{
public:
	Date()//无参的构造函数
	{
		_year = 2023;
		_month = 5;
		_day = 1;
	}
	// 全缺省的构造函数
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}

private:
	int _year;
	int _month;
	int _day; 
};

如上代码,我们已经显示定义了构造函数——一个无参的,一个全缺省的,显然我们要调用时就会有分歧,所以我们规定,调用无参的函数时连括号都不用写:

int mian()
{
	Date d3(2023,4,5);//调用全缺省的构造函数
	return 0;
}

如果类中未显示定义构造函数,编译器则会生成一个无参的默认构造函数。但是自动生成的默认构造函数只会初始化自定义类型不会初始化内置类型(在不同的编译器上有所区别)。内置类型就是语言提供的数据类型如:int/char等,自定义类型就是我们自己定义的类型如:struct/class/union等。
这样问题就来了,日期类中如果我们忘记定义构造函数,因为日期类成员全是内置类型,则编译器自动生成的构造函数无法完成对类成员的初始化,所以在C++11中规定了,内置类型成员变量在类中声明的时候可以给默认值。还有要注意的:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认构造函数。
那么我们什么时候需要自己写构造函数,什么时候用编译器生成的呢:

  1. 一般来说,有内置类型并且内置类型未赋符合要求的缺省值时,就需要我们自己编写构造函数
  2. 如果成员全是自定义类型的则可以使用编译器生成的默认成员函数

三.析构函数。

析构函数就是销毁清理函数,完成对象资源的清理工作,他有以下特征:

  1. 析构函数名是类名前面加上~。
  2. 析构函数无返回值 无参数
  3. 析构函数无法重载,一个类只能有一个析构函数,若未显式定义则编译器自动生成。
  4. 对象生命周期结束时,系统自动调用析构函数。

析构函数与构造函数相似:内置类型不会做处理,自定义类型会调用它的析构函数。
由此判断:

  1. 一般情况下,有动态申请资源,就需要显示写析构函数释放资源
  2. 没有动态申请的资源,不需要写析构
  3. 需要释放资源的成员都是自定义类型,不需要写析构
四.拷贝构造函数

当我们想创建两个成员相同的对象时,可以采用用已经存在的对象初始化,这就要使用到拷贝构造函数。他只有一个形参是对本类型对象的引用,拷贝构造函数时构造函数的一个重载,形参如果不使用引用而采用传值调用的话会引发无穷递归调用——因为内置类型的传值调用需要中间变量拷贝来完成而自定义类型传参的值拷贝需要拷贝构造函数完成
若未显式定义,编译器会自动生成一个默认拷贝构造函数:内置类型会完成值拷贝/浅拷贝,而自定义类型会调用他的拷贝构造函数。
注意:类中如果没有涉及资源申请时,拷贝构造函数是否写都可以,一旦涉及到资源申请时,则拷贝构造函数是一定要写的,否则就是浅拷贝

指针无论是什么类型的都是内置类型。

五.赋值运算符重载

运算符重载是具有特殊函数名的函数。
函数名字为:关键字operator后面接需要重载的运算符符号。
函数原型:返回值类型 operator操作符(参数列表)
运算符重载需要注意一下几点:

  1. 重载操作符必须有一个类类型参数
  2. 用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不 能改变其含义
  3. 不能通过连接其他符号来创建新的操作符:比如operator@
  4. 作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this
  5. .* sizeof :: ?: . 注意以上5个运算符不能重载。

诸如下面的代码就是运算符重载:

// >运算符重载

	bool operator>(const Date& d)
	{
		return !(*this <= d);
	}




	// ==运算符重载
	bool operator==(const Date& d)
	{
		return _year == d._year
			&& _month == d._month
			&& _day == d._day;
	}



	// >=运算符重载
	bool operator >= (const Date& d)
	{
		return !(*this < d);
	}


	// <运算符重载
	bool operator < (const Date& d)
	{
		if (_year < d._year)
		{
			return true;
		}
		else if (_year == d._year && _month < d._month)
		{
			return true;
		}
		else if (_year == d._year && _month == d._month && _day < d._day)
		{
			return true;
		}
		else
		{
			return false;
		}
	}


	// <=运算符重载
	bool operator <= (const Date& d)
	{
		return !(*this > d);
	}


	// !=运算符重载
	bool operator != (const Date& d)
	{
		return !(*this == d);
	}

赋值运算符重载需要注意:

  1. 参数类型:const T&,传递引用可以提高传参效率
  2. 返回值类型:T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值
  3. 检测是否自己给自己赋值
  4. 返回*this :要复合连续赋值的含义
class Date

{ 

public :
 Date(int year = 1900, int month = 1, int day = 1)
 {
 _year = year;
 _month = month;
 _day = day;
 }
 
 Date (const Date& d)
 {
 _year = d._year;
 _month = d._month;
 _day = d._day;
 }
 
 Date& operator=(const Date& d)
 {
 	if(this != &d)
 	{
 		_year = d._year;
 		_month = d._month;
 		_day = d._day;
 	}
 	return *this;
 }

private:
 int _year ;
 int _month ;
 int _day ;
};

还有几点需要注意的!
赋值重载不能写成全局(默认成员函数都不能写成全局函数)但是可以声明和定义分离(也不一定还要注意访问类成员私有共有问题)
C++规定: ++a 前缀运算符 a.operator() 不需要加参数a++后缀运算符 a.operator(int) 需要加参数。
当一元运算符作为成员函数重载时参数表中没有参数,那个惟一的操作数以this指针的形式隐藏在参数表中;当作为非成员函数重载时,那个惟一的操作数必须出现在参数表中。文章来源地址https://www.toymoban.com/news/detail-431423.html

到了这里,关于默认成员函数:详解类的隐式操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++】类的默认成员函数----const成员函数(超详细解析)

    目录 一、前言 二、const成员函数  🍎const修饰类的成员函数  💦问题1  💦问题2 💦针对const成员函数的常考面试题(重点!!) 🍐取地址及const取地址操作符重载 三、共勉    在我们前面学习的 类 中,我们会定义 成员变量 和 成员函数 ,这些我们自己定义的函数都是普

    2024年04月14日
    浏览(44)
  • 【C++】类的默认成员函数(下)

    🔥 博客主页 : 小羊失眠啦. 🎥 系列专栏 : 《C语言》 《数据结构》 《C++》 《Linux》 《Cpolar》 ❤️ 感谢大家点赞👍收藏⭐评论✍️ 本章主要内容为认识与学习C++非常重要的概念—— 运算符重载 。通过 日期类 的实现,逐步学习各个运算符重载的实现方法即含义。6个默

    2024年03月18日
    浏览(47)
  • C++:类的六个默认成员函数

    个人主页 : 个人主页 个人专栏 : 《数据结构》 《C语言》《C++》 本篇博客作为C++知识总结,我们来认识类的六个默认成员函数。 下面我主要以日期类作为示例显示。 构造函数 是一个特殊的成员函数,名字与类名相同,创建类类型对象时(实例化类)由编译器自动调用,以保

    2024年02月08日
    浏览(55)
  • 【浅尝C++】继承机制=>虚基表/菱形虚继承/继承的概念、定义/基类与派生类对象赋值转换/派生类的默认成员函数等详解

    🏠专栏介绍:浅尝C++专栏是用于记录C++语法基础、STL及内存剖析等。 🎯每日格言:每日努力一点点,技术变化看得见。 我们生活中也有继承的例子,例如:小明继承了孙老师傅做拉面的手艺。继承就是一种延续、复用的方式。C++为了提高代码的可复用性,引入了继承机制,

    2024年04月10日
    浏览(48)
  • C++中类的6个默认成员函数 【拷贝构造函数】

    在前几章学习对象的时候,我们有的时候需要一个与已存在对象一某一样的新对象 那在创建对象时,可否创建一个与已存在对象一某一样的新对象呢? 拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象创建新对象时

    2024年02月20日
    浏览(57)
  • 【C++】类和对象②(类的默认成员函数:构造函数 | 析构函数)

    🔥 个人主页: Forcible Bug Maker 🔥 专栏: C++ 目录 前言 类的6个默认成员函数 构造函数 概念 构造函数的特性及用法 析构函数 概念 析构函数的特性及用法 结语 本篇主要内容:类的6个默认成员函数中的 构造函数 和 析构函数 进入到类和对象内容的第二节,上篇博客中介绍了

    2024年04月16日
    浏览(57)
  • C++从入门到精通——类的6个默认成员函数之拷贝构造函数

    类的6个默认成员函数:如果一个类中什么成员都没有,简称为空类。 空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。 默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。 在现实生活中,可

    2024年04月26日
    浏览(50)
  • 【C++初阶】第三站:类和对象(中) -- 类的6个默认成员函数

    目录 前言 类的6个默认成员函数 构造函数 概念 特性 析构函数  概念 特性 拷贝构造函数 概念 特征 赋值运算符重载 运算符重载 赋值运算符重载 const成员 const修饰类成员函数 取地址及const取地址操作符重载 本章总结:         有时候我们写好了一个栈,头脑中第一件事

    2024年02月20日
    浏览(44)
  • 【C++】中类的6个默认成员函数 取地址及const成员函数 && 学习运算符重载 && 【实现一个日期类】

    1.1 运算符重载【引入】 C++为了增强代码的可读性引入了 运算符重载 ,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。 函数名字为: operator后面接需要重载的运算符符号。 函数原型:

    2024年02月21日
    浏览(49)
  • 【C++】类和对象③(类的默认成员函数:拷贝构造函数 | 赋值运算符重载)

    🔥 个人主页: Forcible Bug Maker 🔥 专栏: C++ 目录 前言 拷贝构造函数 概念 拷贝构造函数的特性及用法 赋值运算符重载 运算符重载 赋值运算符重载 结语 本篇主要内容:类的6个默认成员函数中的 拷贝构造函数 和 赋值运算符重载 在上篇文章中我们讲到了类的默认成员函数的

    2024年04月17日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包