C++类中的六大默认成员函数详解
在C++中,当你去创建一个类的时候,即便这个类是空类,也会自动生成下面6个默认成员函数,在本篇博客中,我将逐一分析下面6个默认成员函数。
构造函数
构造函数并不是去构造函数的函数,而是去对函数进行初始化的函数。构造函数的函数名与类名相同,当我们每次创建类对象的时候,就会自动调用构造函数。构造函数在对象的生命周期中只会调用1次。
class Date { public: //构造函数 Date(int year = 2021, int month = 4, int day = 11) { _year = year; _month = month; _day = day; } private: int _year; int _month; int _day; };
构造函数的几个特点:
①函数名与类名相同
②无返回值
③对象实例化时编译器自动调用对应的构造函数
④构造函数可以重载
class Date { public: //构造函数的重载: //无参的构造函数 Date() {} //需要传参的构造函数 Date(int year, int month, int day) { _year = year; _month = month; _day = day; } private: int _year; int _month; int _day; };
⑤如果类中没有显式定义构造函数(就是自己没有去定义构造函数),那么编译器会自动生成一个无参的默认构造函数;
如果类中显式定义了构造函数,那么编译器将不再生成,而是去使用用户定义的构造函数。
⑥默认构造函数只能同时存在1个。默认构造函数分为以下3种:①无参的构造函数 ②全缺省的构造函数 ③编译器默认生成的构造函数
默认构造函数的共同特点是:不用传参就可以调用
class Date { public: //下面2种和 当你不写构造函数时编译器自动生成的默认构造函数只能同时存在1种 //无参的 Date() { _year = 2021; _month = 4; _day = 11; } //全缺省的 Date(int year = 2021, int month = 4, int day = 11) { _year = year; _month = month; _day = day; } private: int _year; int _month; int _day; };
⑦编译器生成的默认的构造函数,对内置类型(int, char, double...)不会做任何处理,但是会针对自定义类型的成员,调用它的构造函数去进行初始
构造函数调用的2种写法:
int main() { //无参时 Date d; //单个参数 Date(1); Date d1 = 2;//这种写法会发生隐式类型转换 //多个参数 Date(2021, 4, 11); Date d2 = {2021, 4, 11};//C++11中才支持的写法 }
构造函数与初始化列表
初始化列表:以冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。
初始化列表有什么用?
初始化列表,顾名思义就是对对象进行初始化的,但是我们已经可以在构造函数体内进行初始化了(通过对成员变量进行赋值来进行初始化),为什么还需要初始化列表?
这是因为,有些类型的数据无法通过在构造函数体内进行赋值来进行初始化。这样的数据类型有下面3种:
- 引用成员变量
- const成员变量
- 自定义类型成员 (且它的类没有默认构造函数[即,它必须要进行传参])
上面的三种数据类型有一个共同的特点,它们都要求你在定义变量的时候进行赋值。
比如,引用成员变量,使用引用的时候必须进行初始化,否则语法就是错误的。
析构函数
析构函数的作用与构造函数相反,在对象的生命周期结束的时候会自动调用析构函数,完成类的一些资源清理的工作。
析构函数的特点:
- 析构函数名是在类名的前面加上~
- 无参,无返回值
- 一个类中有且只有1个析构函数。如果未显式定义,系统会自动生成默认的析构函数。(如果定义了,则采用显式定义的)
- 对象生命周期结束时,C++编译系统会自动调用析构函数
- 编译器生成的默认的析构函数,对内置类型(int, char, double...)不会做任何处理,但是会针对自定义类型的成员,会去调用它的析构函数
析构函数的一般使用情况:
一般使用在那些涉及到动态内存开辟空间的类中,因为这样的对象需要对其动态开辟的空间进行释放。
class Stack { public: //构造函数 Stack(int n = 3) { _a = (int*)malloc(sizeof(int)*n); _size = 0; _capacity = n; } //析构函数 ~Stack() { free(_a); _size = _capacity = 0; } private: int* _a; int _size; int _capacity; };
拷贝构造函数
拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象去创建新的对象时,编译器会自动调用拷贝构造函数。
拷贝构造函数的特点:
- 拷贝构造函数是构造函数的一个重载
- 拷贝构造函数的参数只有1个,且必须使用引用传参,如果使用引用传值的形式会引发无限递归。
拷贝构造函数的2种调用方法(完全等价的):
int main() { Date d1(1); //拷贝构造函数 Date d2(d1); //1 Date d3 = d1; //2 return 0; }
赋值运算符重载
在了解赋值运算符重载之前,我们需要先知道什么是运算符重载。
运算符重载
运算符重载是具有特殊函数名的函数。
函数名:关键字operator后面接需要重载的运算符符号(如:operator>)
函数原型:返回类型 operator操作符 (参数列表)
注意:
- operator后面必须跟着的是操作符(这样是不可以的 operator@)
- 重载操作符必须有一个类类型或者枚举类型的操作数
- 用于内置类型的操作符,其含义无法改变。(比如内中的整型+,3+5这其中的+的意义不会改变)
- this指针为限定的第一个形参,也就是this作为第一个操作数
- .*、::、sizeof、?:、. 这5个操作符无法进行重载。
赋值运算符重载
class Date { public: Date(int year = 2021, int month = 4, int day = 11) { _year = year; _month = month; _day = day; } //赋值运算符重载 Date& operator=(const Date& d) { _year = d._day; _month = d._month; _day = d._day; return *this; } private: int _year; int _month; int _day; };
注意:赋值运算符重载必须有返回值,如果没有返回值的话,无法解决 a = b = c 这种连续赋值的操作。
拷贝构造函数与赋值运算符重载
Date d1(1); Date d2(0); //赋值运算符重载 d2 = d1; //注意,只有2个操作数都是已经定义过的变量时,才会调用赋值运算符重载 //拷贝构造函数 Date d3(d1);
浅拷贝
浅拷贝是你在没有写拷贝构造函数和operator=时,编译器自动调用的默认成员函数。它的功能是将对象以字节的为单位拷贝过去。
取地址与const取地址操作符重载
这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可(编译器默认的基本就够用了),只有特殊情况,才需要重载,比如想让别人获取到指定的内容。
class Date { public: //取地址操作符重载 Date* operator&() { return this; } //const取地址操作符重载 const Date* operator&()const { return this; } private: int _year; int _month; int _day; };
到此这篇关于C++类中的六大默认成员函数的文章就介绍到这了,更多相关C++类默认成员函数内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!
class Date { public: //初始化列表 Date(int year, int month, int day) :_year(year), _month(month), _day(day) {} private: int _year; int _month; int _day; };
相关文章
- 以前我们开发大型项目时都会用到svn来同步,因为开发产品的人过多,所以我们会利用软件来管理,今天发有一居然可以利用php来管理svn哦,好了看看吧。 代码如下 ...2016-11-25
- vector是表示可以改变大小的数组的序列容器,本文主要介绍了C++STL标准库std::vector的使用详解,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2022-03-06
- 操作类就是把一些常用的一系列的数据库或相关操作写在一个类中,这样调用时我们只要调用类文件,如果要执行相关操作就直接调用类文件中的方法函数就可以实现了,下面整理了...2016-11-25
- 这篇文章主要介绍了C++中取余运算的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
- 这篇文章主要介绍了C++ string常用截取字符串方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
- 本文通过例子,讲述了C++调用C#的DLL程序的方法,作出了以下总结,下面就让我们一起来学习吧。...2020-06-25
- 本篇文章主要介绍了C++中四种加密算法之AES源代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。...2020-04-25
- 整数拆分,指把一个整数分解成若干个整数的和。本文重点给大家介绍C++ 整数拆分方法详解,非常不错,感兴趣的朋友一起学习吧...2020-04-25
- 本文实例讲述了JS+CSS实现分类动态选择及移动功能效果代码。分享给大家供大家参考,具体如下:这是一个类似选项卡功能的选择插件,与普通的TAb区别是加入了动画效果,多用于商品类网站,用作商品分类功能,不过其它网站也可以用,...2015-10-21
- 本文章来人大家介绍一个php文件上传类的使用方法,期望此实例对各位php入门者会有不小帮助哦。 简介 Class.upload.php是用于管理上传文件的php文件上传类, 它可以帮...2016-11-25
- 这篇文章主要介绍了C++中Sort函数详细解析,sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变...2022-08-18
- 这篇文章主要介绍了C++万能库头文件在vs中的安装步骤(图文),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
- 无限级分类在开发中经常使用,例如:部门结构、文章分类。无限级分类的难点在于“输出”和“查询”,例如 将文章分类输出为<ul>列表形式; 查找分类A下面所有分类包含的文章。1.实现原理 几种常见的实现方法,各有利弊。其中...2015-10-23
- 在一些复杂的系统中,要求对信息栏目进行无限级的分类,以增强系统的灵活性。那么PHP是如何实现无限级分类的呢?我们在本文中使用递归算法并结合mysql数据表实现无限级分类。 递归,简单的说就是一段程序代码的重复调用,当把...2015-10-23
- 这篇文章主要介绍了C#类中static变量用法,实例分析了static变量使用技巧与相关注意事项,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了mybatis-plus实体类主键策略有3种(小结),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-08-27
- 这篇文章主要介绍了C++ bitset用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
- 本篇文章小编并不是为大家讲解string类型的用法,而是讲解我个人比较好奇的问题,就是string 类型占几个字节...2020-04-25
- ecshop商品无限级分类代码 function cat_options($spec_cat_id, $arr) { static $cat_options = array(); if (isset($cat_options[$spec_cat_id]))...2016-11-25
- 这篇文章主要为大家详细介绍了C++ Eigen库计算矩阵特征值及特征向量,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-04-25