c++类和对象新手保姆级上手教学(中)

这篇具有很好参考价值的文章主要介绍了c++类和对象新手保姆级上手教学(中)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言:

  类和对象中篇,这里讲到的前4个默认成员函数,是类和对象中的重难点,许多资料上的讲法都非常抽象,难以理解,所以我作出这篇总结,分享学习经验,以便日后复习。

目录

6个默认成员函数:

构造函数:

1.概念:

2.用法:

3.特性:

 析构函数:

1.概念:

2.用法:

 3.特性:

4.析构调用顺序练习:

拷贝构造函数:

1.概念:

2.用法:

3.特性:

运算符重载:

用法:

赋值重载:

前置++和后置++重载:

 取地址重载(不重要):

const成员函数:

 


6个默认成员函数:

什么是默认成员函数?

默认成员函数就是你不写编译器自己会自动生成的成员函数

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

前四个默认成员函数较为重要,后两个很少会自己实现,除非常特殊的情况下,基本上不会自己实现。

构造函数:

1.概念:

  想必大家再用c语言实现栈,链表等数据结构的时候,都会先写一个初始化函数,来初始化我们的数据,但在使用中有时往往会忘记初始化,所以C++就产生了构造函数。

构造函数的作用就是进行初始化

2.用法:

  那构造函数具体是怎样来使用的呢?举一个简单的案例,一个日期类的构造函数如下:

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

3.特性:

  构造函数的函数名和类名相同。

  无返回值。

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

  构造函数支持重载。

  建议写成全缺省。 

  一个类必须要有默认构造函数,如果你没有写,编译器会自己生成默认构造函数,但编译器默认生成的构造函数内置类型不作处理,自定义类型去调用它的默认构造函数。但在C++11中委员会可能认为对内置类型不作处理显得很呆,所以对这个语法打补丁,支持在声明处给缺省值:

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

这样编译器默认生成的构造函数就会对内置类型进行处理。 

  但大多数情况下,构造函数都是需要我们自己去实现的。

无参构造函数,全缺省构造函数,编译器默认生成的构造函数,都可以称为默认构造函数,但一个类默认构造函数只能有一个,建议写成全缺省,避免歧义。

 析构函数:

1.概念:

  如果说构造函数的功能时初始化,那么析构函数就像它的死对头:

析构函数负责清理资源的工作,防止内存泄漏。

 还是一样,我们在使用栈,链表等数据结构时最容易忘的就是用完后忘记清理空间,这将导致严重的后果,也就是内存泄漏,而C++中的析构函数可以有效解决这个问题。

2.用法:

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

由于我这个日期类不涉及动态资源,所以析构函数不必自己实现,但仍会调用:

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

 3.特性:

 函数名 = ~类名

 无返回值

 一个类只能有一个析构函数,如果不写编译器自己生成

 析构函数不能重载

 对象生命周期结束时,编译器自动调用析构函数

 对于编译器自己生成的析构函数,同样是内置类型不作处理,自定义类型调用它自己的析构函数。

4.析构调用顺序练习:

对于析构函数,其实头疼的是它的多个函数析构时的调用顺序,这里给大家一个公式,大家以后套公式即可:

局部对象(后定义先析构)->局部静态(后定义先析构)->全局对象(后定义先析构)

下面由浅入深来练习一下: 

练习1: 

#include<iostream>
using namespace std;
class Date
{
public:
	Date(int year=1,int month=1,int day=1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}
	~Date()
	{
		cout << "调用析构" << _year << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(1);
	Date d2(2);
	Date d3(3);
	return 0;
}

因为他们都是局部变量,遵循后定义先析构,所以:

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

练习2:

#include<iostream>
using namespace std;
class Date
{
public:
	Date(int year=1,int month=1,int day=1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}
	~Date()
	{
		cout << "调用析构" << _year << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
Date d1(1);
Date d2(2);
Date d3(3);
int main()
{
	//Date d1(1);
	//Date d2(2);
	//Date d3(3);
	return 0;
}

 现在他们都变为全局变量,仍遵循后定义先析构:

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

练习3:

#include<iostream>
using namespace std;
class Date
{
public:
	Date(int year=1,int month=1,int day=1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}
	~Date()
	{
		cout << "调用析构" << _year << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(1);
	static Date d2(2);
	static Date d3(3);
	Date d4(4);
	return 0;
}

 现在,d2变成局部静态,根据公式,先局部对象再局部静态,内部仍然按照后定义先析构:

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

练习4:

#include<iostream>
using namespace std;
class Date
{
public:
	Date(int year=1,int month=1,int day=1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}
	~Date()
	{
		cout << "调用析构" << _year << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
Date d5(5);
static Date d6(6);
Date d7(7);
static Date d8(8);
int main()
{
	Date d1(1);
	static Date d2(2);
	static Date d3(3);
	Date d4(4);
	return 0;
}

 先局部对象,再局部静态,最后全局,不管全局对象是否为静态,都遵循后定义先析构:

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

拷贝构造函数:

1.概念:

 在使用C++中,我们往往会需要将一个类拷贝到另一个相同类型的类中,而拷贝构造函数的作用就是:将该类拷贝到同类型的类中。

2.用法:

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

为了更严谨,也可以在此处加上const:

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

 

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

3.特性:

 函数名和类名相同

 无返回值

 形参部分传引用

 拷贝构造函数也是构造函数

 如果我们不写,编译器会默认生成,默认生成的拷贝构造函数对内置类型成员按内存存储按字节序拷贝,也就是浅拷贝,对自定义成员调用它的拷贝构造。

为什么形参部分必须传引用呢?

因为不传引用可能会引发无穷递归,看下面这个例子:

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

此时像上图一样使用拷贝构造函数,如果我们的拷贝构造函数是传值:

 

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

那就需要先调用拷贝构造,调用到拷贝构造时,因为是传值,所以需要将d1先拷贝到形参d,而将d1拷贝到形参d,就又需要调用新的拷贝构造,而新的拷贝构造又是传值,所以就这样一直递归下去,无穷无尽。

编译器默认生成的拷贝构造会拷贝内置类型,那么是不是意味着我们不需要自己实现拷贝构造?

不!!!

编译器默认生成的拷贝构造只能进行浅拷贝。

当我们有一个栈,里面有一个指针,指向了一片空间,当我们还是浅拷贝,用编译器默认生成的拷贝构造函数的话,它就会原原本本的将指针的拷贝到新的指针中,这就导致这篇空间有两个指针指向它,而不是像我们预想的一样,拷贝一块新空间,所以当要进行深拷贝时,我们需要自己来写拷贝构造函数 

所以写拷贝构造时,浅拷贝不需要写,只有有动态资源开辟的,才需要自己写拷贝构造。

运算符重载:

关键字:operator

用法:

将函数名改成operator加需要重载的运算符

在c语言中,对于内置类型我们可以直接用<  >  =  +  -  等符号进行运算,但如果我们要对自定义类型进行运算的话,就需要自己写函数来实现。

如果用运算符重载的话,将大大提高代码的可读性,比如我们实现一个判断两个日期类是否相同,重载==:

重载成成员函数:

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

重载成全局函数: 

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

 用法:

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

显而易见,第三种方法最实用,大大提高了代码的可读性 。

赋值重载:

这里的内容涉及的运算符重载,建议先跳到运算符重载,再来学习这段。

区分拷贝和赋值:

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

众所周知自定义类型是不能直接用等号连接进行赋值的,那么就需要进行运算符重载;

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

赋值重载和拷贝构造类似,但赋值重载是支持连续赋值的:

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

注意赋值重载只能重载成成员函数。 

前置++和后置++重载:

前置++和后置++这两个运算符一模一样,但是作用效果却不同,为了不产生歧义,该如何进行重载呢?

前置++:

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

用法:

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

后置++: 

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

用法 :

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

可见为了和前置++区分开来,后置++强制增加了一个形参int 来区分。 

 取地址重载(不重要):

主要是对对象进行取地址操作,编译器自己生成的已经完全够用,没有必要再自己写,除非有特殊需求:

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

const成员函数:

如果我们希望某个成员函数不能对成员变量进行修改时,我们可以进行const修饰:

用法: 

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

我们可以对不用对成员变量进行修改的成员函数进行const修饰,增加代码的严谨性。如果const修饰的成员函数对成员变量进行了修改,编译器会报错:

c++类和对象新手保姆级上手教学(中),c++,c++,开发语言,类和对象,默认成员函数,构造函数,析构函数,运算符重载

C++类和对象中篇到此结束,这篇是最难也是最重要的一篇,下篇我会陆续更新进行收尾。 文章来源地址https://www.toymoban.com/news/detail-831601.html

 

到了这里,关于c++类和对象新手保姆级上手教学(中)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • <C++> 类和对象(上)-面向对象

    C语言是 面向过程 的,关注的是过程,分析出求解问题的步骤, 通过函数调用逐步解决问题。 C++是基于 面向对象 的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。 C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函

    2024年02月11日
    浏览(53)
  • 【C++】类和对象(上篇)

    目录 一、类的引入 二、类的定义 三、类的访问限定符及封装   1、访问限定符   2、封装 四、类的作用域 五、类的实例化 六、类对象模型   1、计算类对象的大小   2、类对象的存储方式   3、结构体/类内对齐规则 七、this 指针   1、this 指针的引出   2、this 指针的特性 首

    2024年02月09日
    浏览(73)
  • 【C++】类和对象-封装

    在main函数前重新补上isSame函数 在Cube类里面添加issamebyclass,利用成员函数判断两个立方体是否相等 自己写的代码: B站视频链接: https://www.bilibili.com/video/BV1et411b73Z/?p=105spm_id_from=333.1007.top_right_bar_window_history.content.clickvd_source=fb8dcae0aee3f1aab700c21099045395

    2024年02月15日
    浏览(47)
  • 【C++】类和对象(3)

    首先我们先回顾一下构造函数,对象的初始化由构造函数来完成,我们可以在构造函数的函数体内对对象的成员变量进行赋值,但这就有一个问题,如下: 答案:显然不是,因为变量只能定义一次。 也就是说,构造函数的函数体内部并不是初始化的地方(定义的地方),而

    2024年02月06日
    浏览(33)
  • 【C++】类和对象(上)

    个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【C++之路】 C语言是面向过程的,而C++是面向对象的,那面向过程和面向对象到底是什么呢? 我们拿一个非常典型的 外卖系统 来进行举例: 面向过程: 我们知道外面

    2024年02月02日
    浏览(44)
  • 【C++】类和对象(中篇)

    在往期 类和对象(上篇) 中,我们初步接触了C++中的类和对象,接下来我会和大家分享有关这个知识点更多的内容~ 如果一个类中什么成员都没有,简称为空类。空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成默认成员函数。 默认成员函数:用户

    2024年02月15日
    浏览(57)
  • 【C++】类和对象(四)

    前言:在类和对象中,我们走过了十分漫长的道路,今天我们将进一步学习类和对象,类和对象这块荆棘地很长,各位一起加油呀。 💖 博主CSDN主页:卫卫卫的个人主页 💞 👉 专栏分类:高质量C++学习 👈 💯代码仓库:卫卫周大胖的学习日记💫 💪关注博主和博主一起学习

    2024年02月19日
    浏览(33)
  • 【C++】:类和对象(1)

    朋友们、伙计们,我们又见面了,本期来给大家解读一下有关C++中类和对象的知识点,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成! C 语 言 专 栏: C语言:从入门到精通 数据结构专栏: 数据结构 个  人  主  页 : stackY、 目录 1.面向过程和面

    2024年02月08日
    浏览(36)
  • 【C++】类和对象(上篇)

    🚩 C语言 是 面向过程 的, 关注 的是 过程 ,分析出求解问题的步骤,通过函数调用逐步解决问题 🚩 C++ 是基于 面向对象 的, 关注 的是 对象 ,将一件事情拆分成不同的对象,靠对象之间的交互完成 🌰 比如: C语言结构体中只能定义变量, 在C++中,结构体内不仅可以定

    2024年01月22日
    浏览(39)
  • c++类和对象(封装)

            C++面向对象的三大特性为: 封装、继承、多态         C++认为万事万物都皆为对象,对象上有其属性和行为 例如:         人可以作为对象,属性有姓名、年龄、身高、体重...,行为有走、跑、跳、吃饭、唱歌...车也可以作为对象,属性有轮胎、方向盘、

    2024年02月08日
    浏览(49)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包