c++中类的6个默认成员函数

 构造函数

构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,保证每个数据成员 都有 一个合适的初始值,并且在对象的生命周期内只调用一次。

构造函数是特殊的成员函数,需要注意的是,构造函数的虽然名称叫构造,但是需要注意的是构造函数的主 要任务并不是开空间创建对象,而是初始化对象。

其特征如下:

1. 函数名与类名相同。

2. 无返回值。

3. 对象实例化时编译器自动调用对应的构造函数。

4. 构造函数可以重载。

class Date
{friend ostream& operator<<(ostream& out, Date& d);
public:// 1.无参构造函数Date(){}// 2.带参构造函数Date(int year, int month, int day){this->_year = year;_month = month;_day = day;}private:int _year;int _month;int _day;
};
ostream& operator<<(ostream& out, Date& d) {out << d._year << d._month << d._day << endl;return out;
}
void main()
{Date d1; // 调用无参构造函数Date d2(2015, 1, 1); // 调用带参的构造函数cout << d1;cout << d2;// 注意:如果通过无参构造函数创建对象时,对象后面不用跟括号,否则就成了函数声明// 以下代码的函数:声明了d3函数,该函数无参,返回一个日期类型的对象//Date d3();
}

打印时没有调用Print()函数,而是用了运算符重载。使得打印更加方便。

传&是为了减少对拷贝构造的调用。 

调无参构造后d1为随机值。

如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定 义编译器将不再生成。

无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。注意:无参 构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认成员函数。

析构函数

析构函数:

与构造函数功能相反,析构函数不是完成对象的销毁,局部对象销毁工作是由编译器完成的。而 对象在销毁时会自动调用析构函数,完成类的一些资源清理工作。

特性

析构函数是特殊的成员函数。

其特征如下:

1. 析构函数名是在类名前加上字符 ~。

2. 无参数无返回值。

3. 一个类有且只有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。

4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。

例子:

vector:

template <class T>
class vector
{
public:vector(): _a(nullptr), _size(0), _capacity(0){}~vector(){delete[]_a;_a = nullptr;_size = _capacity = 0;}void push_back(const T& x);/*{}*/void pop_back();size_t size(){return _size;} T& operator[](size_t i){assert(i < _size);return _a[i];}
private:T* _a;size_t _size;size_t _capacity;
};

拷贝构造函数

概念

在现实生活中,可能存在一个与你一样的自己,我们称其为双胞胎。

 构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象 创建新对象时由编译器自动调用。

拷贝构造函数也是特殊的成员函数,其特征如下:

1. 拷贝构造函数是构造函数的一个重载形式。

2. 拷贝构造函数的参数只有一个且必须使用引用传参,使用传值方式会引发无穷递归调用。

以日期类为例实现拷贝构造函数。

//拷贝构造
Date(const Date& d)
{this->_year = d._year;_month = d._month;_day = d._day;
}

日期的拷贝属于浅拷贝,编译器会生成。

若未显示定义,系统生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷 贝,这种拷贝我们叫做浅拷贝,或者值拷贝。

但深拷贝的拷贝构造,需要自己构思。 

 传值的本质是拷贝构造,而拷贝构造又需要传参,故上图会陷入循环。

避免拷贝构造最好的方式就是使用&(引用)。

赋值运算符重载

运算符重载

C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类 型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。

函数名字为:关键字operator后面接需要重载的运算符符号。

函数原型:返回值类型 operator操作符(参数列表)

注意:

不能通过连接其他符号来创建新的操作符:比如operator@

重载操作符必须有一个类类型或者枚举类型的操作数

用于内置类型的操作符,其含义不能改变,例如:内置的整型+,不 能改变其含义

作为类成员的重载函数时,其形参看起来比操作数数目少1成员函数的

操作符有一个默认的形参this,限定为第一个形参

.* 、:: 、sizeof 、?: 、. 注意以上5个运算符不能重载。

以日期类为例:

#define _CRT_SECURE_NO_WARNINGS 
#include <iostream>
using namespace std;
class Date
{friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator >> (istream& in, Date& d);
public://d2(d1) d2.Date(d1)int GetMouthDay(int year, int mouth) {static int days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };int day = days[mouth];if (mouth == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) {day += 1;}return day;}Date(){}Date(int year, int mouth, int day){this->_year = year;this->_mouth = mouth;this->_day = day;}void Print() {cout << _year << this->_mouth << this->_day;}//d1>d2--->!(d1<=d2)bool operator>(const Date& d){return !(*this <= d);}bool operator>=(const Date& d){return !(*this < d);}bool operator==(const Date& d) {if (this->_year == d._day && this->_mouth == d._mouth && this->_day == d._day){return true;}return false;}bool operator!=(const Date& d){return !(*this == d);}//d1<d2//d1.operator<(&d1,d2)inline bool operator<(const Date& d){if (this->_year < d._year){return true;}else if (this->_year == d._year && _mouth < d._mouth){return true;}else if(_year==d._year&&_mouth==d._mouth&&_day<d._day){return true;}return false;}bool operator <= (const Date & d){return *this < d || *this == d;}//d1+=10Date& operator += (int day){this->_day += day;while (_day > GetMouthDay(this->_year, this->_mouth)){_day -= GetMouthDay(this->_year, this->_mouth);_mouth++;if (_mouth == 13){++_year;_mouth = 1;}}return *this;}Date operator+(int day){Date ret(*this);ret += day;//ret.operator+=(day);return ret;}//d1+=10----d1.operator(&d1,10)Date& operator-=(int day) {this->_day -= day;while (this->_day <=0){this->_mouth--;if (_mouth == 0){--_year;_mouth = 12;}this->_day += GetMouthDay(_year, _mouth);     }return *this;}Date operator-(int day){Date ret = *this;ret._day -= day;while (ret._day<=0){ret._mouth--;if (ret._mouth == 0){--ret._year;ret._mouth = 12;}ret._day += GetMouthDay(ret._year, ret._mouth);}return ret;}//++d1--->d1.operator++(&d1)Date& operator++(){*this += 1;return *this;//返回加之后的值}//d1++--->d1.operator++(&d1,0)Date operator++(int){Date tmp(*this);*this += 1;return tmp;}//d1-d2  利用n返回d1和d2所相差的天数int operator-(const Date& d) {int flag = 1;Date max = *this;//拷贝构造---浅拷贝---编译器可以自动生成Date min = d;if (*this < d){max = d;min = *this;flag = -1;}int n = 0;while (min != max&&min<max) {++min;++n;}return n+1;}void Scanf() {scanf("%04d%02d%02d", &this->_year, &this->_mouth, &this->_day);}cour->ostreamcin->istreamprivate:int _year;int _mouth;int _day;
};
ostream& operator<<(ostream& out, const Date& d)
{out << d._year <<d._mouth << d._day << endl;return out;
}
istream& operator >> (istream& in, Date& d){in >>  d._year >> d._mouth >> d._day;return in;}int main() {/*Date d1(0, 1, 1);Date d2(0, 1, 1);*//*Date d1(2022,2,10);Date d2(2022, 2, 1);*///cin >> d1 >> d2;/*while (cin>>d1>>d2){cout << d1 << d2;}*/Date d1, d2;//&& d2.Scanf()/*while (cin>>d1>>d2) {cout << d1 - d2;}*/d1.Scanf();d2.Scanf();/* cout << d1<<endl;cout << d2<<endl;*/cout << d1 - d2;
}
// 64 位输出请用 printf("%lld")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/543346.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024.04

每一点建议都会包含为什么这么做的理由&#xff0c;帮助用户理解每个步骤背后的重要性和效果。 b004071ozy_05_amzn 第三步&#xff1a;授权开通资源中心&#xff08;点开通后&#xff0c;需要等待几分钟时间&#xff09; 图片 本文由 mdnice 多平台发布

深入了解 大语言模型(LLM)微调方法

引言 众所周知&#xff0c;大语言模型(LLM)正在飞速发展&#xff0c;各行业都有了自己的大模型。其中&#xff0c;大模型微调技术在此过程中起到了非常关键的作用&#xff0c;它提升了模型的生成效率和适应性&#xff0c;使其能够在多样化的应用场景中发挥更大的价值。 那么&…

C++的类和对象(七):友元、内部类

目录 友元 友元函数 友元类 内部类 匿名对象 拷贝对象时的一些编译器优化 再次理解类和对象 友元 基本概念&#xff1a;友元提供了一种突破封装的方式&#xff0c;有时提供了便利&#xff0c;但是友元会增加耦合度&#xff0c;破坏了封装&#xff0c;所以友元不宜多用&…

记录工作中莫名其妙的bug

1、问题&#xff1a;办公室的电脑突然除了我之外&#xff0c;都不能访问我们的线上系统了 原因&#xff1a;因为是内网&#xff0c;同事有刚刚升级了Windows11&#xff0c;配置的DNS被清了&#xff0c;还有同事换了公司的新电脑&#xff0c;还没有配DNS 位于&#xff1a;C /Win…

C#,入门教程(27)——应用程序(Application)的基础知识

上一篇: C#,入门教程(26)——数据的基本概念与使用方法https://blog.csdn.net/beijinghorn/article/details/124952589 一、什么是应用程序 Application? 应用程序是编程的结果。一般把代码经过编译(等)过程,最终形成的可执行 或 可再用 的文件称为应用程序。可执行文…

vue3项目随笔1

1,Eslint Prettier 报错情况&#xff1a; 解决办法&#xff1a; &#xff08;1&#xff09;下载Prettier - code formatter &#xff08;2&#xff09;配置setting.json文件 文件 -> 首选项 -> 设置 -> 用户 -> Eslint "editor.defaultFormatter":…

北斗卫星在桥隧坡安全监测领域的应用及前景展望

北斗卫星在桥隧坡安全监测领域的应用及前景展望 北斗卫星系统是中国独立研发的卫星导航定位系统&#xff0c;具有全球覆盖、高精度定位和海量数据传输等优势。随着卫星导航技术的快速发展&#xff0c;北斗卫星在桥隧坡安全监测领域正发挥着重要的作用&#xff0c;并为相关领域…

c语言的字符串函数详解

文章目录 前言一、strlen求字符串长度的函数二、字符串拷贝函数strcpy三、链接或追加字符串函数strcat四、字符串比较函数strcmp五、长度受限制字符函数六、找字符串2在字符串1中第一次出现的位置函数strstr七、字符串切割函数strtok&#xff08;可以切割分隔符&#xff09;八、…

【python】爬取杭州市二手房销售数据做数据分析【附源码】

一、背景 在数据分析和市场调研中&#xff0c;获取房地产数据是至关重要的一环。本文介绍了如何利用 Python 中的 requests、lxml 库以及 pandas 库&#xff0c;结合 XPath 解析网页信息&#xff0c;实现对链家网二手房销售数据的爬取&#xff0c;并将数据导出为 Excel 文件的过…

day-21 前 K 个高频元素

思路&#xff1a;用ans[]存储频次最高的k个元素&#xff0c;用anslen[]存储对应的索引&#xff0c;将nums进行排序依次统计每个元素出现次数&#xff0c;再判断是否需要对ans[]和anslen[]进行替换&#xff0c;最后ans即为答案 注意点&#xff1a;遍历结束后&#xff0c;还需要…

linux 使用docker安装 postgres 教程,踩坑实践

linux 使用docker安装 postgres 教程 踩坑实践,安装好了不能远程访问。 防火墙已关闭、postgres 配置了允许所有ip 访问、网络是通的。端口也是开放的&#xff0c;就是不能用数据库链接工具访问。 最后发现是云服务器端口没开 ,将其打开 到这一步完全正确了&#xff0c;但是…

Java项目:56 ssm681基于Java的超市管理系统+jsp

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 功能包括:商品分类&#xff0c;供货商管理&#xff0c;库存管理&#xff0c;销售统计&#xff0c;用户及角色管理&#xff0c;等等功能。项目采…