返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++进一步认识类与对象
  • 620
分享到

C++进一步认识类与对象

2024-04-02 19:04:59 620人浏览 独家记忆
摘要

目录赋值操作符重载函数1.运算符重载2.赋值运算符重载3.默认的赋值操作符重载函数4.赋值重载函数与拷贝构造函数的对比日期类的实现const成员1.const修饰类的成员函数2.小结

赋值操作符重载函数

1.运算符重载

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

其函数名为: operator + 需要重载的运算符符号(参数列表)。

需要注意的是:

(1)不能通过连接其他符号来创建新的操作符,比如operator$.也就是说,operator只能重载已有的操作符,其他的符号不能通过该函数来创造。

(2)重载操作符必须有一个类类型或枚举类型的操作数。

(3)用于内置类型的操作符,其含义不能改变。比如,内置整型的==,不能改变其类型。

(4)运算符重载函数的参数个数为操作符的操作数个数,比如对于==操作符,其操作数由两个,那么重载该操作符的函数参数应为2个,即operator==(int x,int y);

(5)对于作为类成员的操作符重载函数,其参数看起来要比操作符的操作数个数少一个,这是因为函数隐含了一个形参this,并且this指针被限定为第一个形参。

(6)语法规定,有五个操作符不能被重载,即.*(成员中指针解引用)、::(作用域限定符)、?:(三目操作符)、.(成员(对象)选择)、sizeof(长度运算符)。这里需要注意的是.(解引用操作符)可以被重载,不能被重载的操作符为s1.*ptr中的.*操作符,即访问类中指针成员并解引用。

用我们熟悉的日期类来举例,比如我们要实现==这个操作符的重载函数:


//头文件Date.h中
class Date
{
public:
	//获取某年某月的天数
	int GetDay(int year, int month)
	{
		assert(month > 0 && month < 13);
		int Day[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
		if (month == 2 && year % 4 == 0 && year % 100 != 0 || year % 400 == 0)//闰年二月
		{
			return 29;
		}
		return Day[month];
	}
	//全缺省的构造函数
	Date(int year = 0, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
		//判断初始化的日期是否合理
		if (_month >= 13 || _day > GetDay(_year, _month) || _month <= 0 || _day <= 0
			|| _year < 0)
		{
			cout << _year << "/" << _month << "/" << _day << "->";
			cout << "非法日期" << endl;
		}
	}
	void Print()
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}
	//拷贝构造函数,d1(d2)
	Date(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	//==运算符重载
	bool operator==(const Date& d) const;
private:
	int _year;
	int _month;
	int _day;
};
//源文件Date.cpp中
//需要注意,左操作数为this指针指向的调用函数的对象,
//即函数等价于bool operator==(Date* this, const Date d);
bool Date::operator==(const Date& d) const
{
	return this->_year == d._year
		&& this->_month == d._month
		&& this->_day == d._day;
}

由于==操作符的结果为真或假,因此函数的返回值设为bool类型。

2.赋值运算符重载

我们知道赋值运算符为=,那么重载赋值运算符的函数应为:


//Date.cpp中
Date& Date::operator=(const Date& d)
{
	if (this != &d)//排除两个操作数相同的情况
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	return *this;
}

需要注意的是:

(1)首先,为了减少形参拷贝导致的开销,我们用引用作为形参类型;其次,由于函数并不会修改原操作数,因此加上const可以保证代码的安全性。

(2)这里的*this即this所指向的对象出了这个赋值重载函数并不会销毁,因此可以用引用返回,返回类型为类名加引用。

(3)如果操作数为两个相同的对象,回导致赋值操作多余,因此需要检查是否出现自己给自己赋值的情况。

3.默认的赋值操作符重载函数

一个类如果没有显式定义赋值运算符重载,编译器也会生成一个,完成对象按字节序的浅拷贝(值拷贝)。

以上面的Date类为例,在我们不实现赋值操作符重载函数的情况下:


int main()
{
    Date d1(2021,10,15);
    Date d2;
    //这里d2回调用编译器自己生成的operator=函数完成拷贝
    //即d2.operator=(d1);
    d2 = d1;
    return 0;
}

和拷贝构造函数一样,编译器生成的默认赋值重载函数已经可以完成字节序的值拷贝了,对于Date类这样的我们无需自己定义,但是对于Stack这样会向内存申请空间的类,不能直接调用编译器的默认函数,会对已经释放的空间重复释放。

4.赋值重载函数与拷贝构造函数的对比

赋值重载函数与拷贝构造函数的作用都是实现字节序的拷贝,那么二者之间有什么区别呢?

首先,拷贝构造函数是构造函数的一个函数重载形式,其函数名为类名,无返回值,而赋值重载函数为=这个操作符的重载,其函数名为operator=,返回值为类名,需要注意的是函数重载与操作符重载二者之间没有任何关联。

其次,一个对象在初始化时调用的时拷贝构造函数,而对象初始化完成后再调用即为赋值重载函数,比如:


int main()
{
    Date d1(2021,10,15);
    //调用拷贝构造函数,相对于Date d2(d1);
    Date d2 = d1;
    Date d3(2021,10,15);
    Date d4;
    //调用赋值重载函数,即d4.operator=(d3);
    d4 = d3;
    return 0;
}

最后,由于=可以连续使用,因此赋值重载函数可以连续调用,比如:


int main()
{
    Date d1(2021,10,15);
    Date d2;
    Date d3;
    //连续调用,相当于,d3 = (d2 = d1); 而d2 = d1有一个返回值
    //该返回值再作为操作数赋值给d3
    //也就相当于d3.operator(d2.operator(d1));
    d3 = d2 = d1;
    return 0;
}

日期类的实现

学习完操作符重载,我们可以实现操作符==、+=、-=、>、<等等。


	//赋值运算符重载,d2=d3 -> d2.operater=(d3)
	Date& operator=(const Date& d);//由于在类域中this所指向的对象并不会销毁,因此可以用引用返回
	//日期+=天数
	Date& operator+=(int day);
	//日期+天数
	Date operator+(int day) const;
	//日期-=天数
	Date& operator-=(int day);
	//日期-天数
	Date operator-(int day) const;
	//前置++
	Date& operator++();
	//后置++
	Date operator++(int);
	//前置--
	Date& operator--();
	//后置--
	Date operator--(int);
	//==运算符重载
	bool operator==(const Date& d) const;
	//!=运算符重载
	inline bool operator!=(const Date& d) const;
	//>运算符重载
	bool operator>(const Date& d);
	//<运算符重载
	inline bool operator<(const Date& d);
	//>=运算符重载
	inline bool operator>=(const Date& d);
	//<=运算符重载
	inline bool operator<=(const Date& d);
	//日期 - 日期,返回天数
	int operator-(const Date& d) const;

const成员

我们先来看看下面这个代码:


	//>运算符重载
	bool operator>(const Date& d);
	void Test6()
{
	const Date d1(2021, 10, 16);
	Date d2 = d1 + 100;
	cout << (d1 > d2) << endl;
}

在这里插入图片描述

实际运行过程中会发现d1 > d2这句代码编译不过去,这是因为隐含的this指针默认的类型为不加const修饰的指针类型,而d1的类型为const修饰的变量,因此传参给this后放大了修改的权限,导致出现错误。但是this指针的类型我们是无法修改的,那么要怎么解决这种情况呢?这就需要用到我们接下来要介绍的const修饰类的成员函数了。

1.const修饰类的成员函数

将const修饰的类成员函数称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。

比如说上述代码我们可以修改为:


	//>运算符重载,其相当于bool operator>(const Date* this, const Date& d);
	bool operator>(const Date& d) const;

2.小结

1.成员函数加const,变成const成员函数,这样既可以让const对象调用,也可以让非const对象调用。

2.不是所有的成员函数都要加const,因为有的函数需要用this指针修改成员变量。

3.一个成员函数是否要加const应看其功能,若为修改型,比如operator+=();Push();等不需要加const;而对于只读型,Print();operator+();等就最好加上const。

综上,如果要修改成员就不加const,若不修改则最好加上const。

取地址及const取地址操作符重载函数

类的最后两个默认成员函数为操作符&的重载及其加上const修饰的函数。


class Date
{ 
public :
 Date* operator&()
 {
 return this ;
 }
 const Date* operator&()const
 {
 return this ;
 }
private :
 int _year ; // 年
 int _month ; // 月
 int _day ; // 日
};

这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,比如想让别人获取到指定的内容!但在实际过程中应用不多。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: C++进一步认识类与对象

本文链接: https://lsjlt.com/news/155095.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++进一步认识类与对象
    目录赋值操作符重载函数1.运算符重载2.赋值运算符重载3.默认的赋值操作符重载函数4.赋值重载函数与拷贝构造函数的对比日期类的实现const成员1.const修饰类的成员函数2.小结...
    99+
    2024-04-02
  • C++初识类和对象
    目录一.初步认识面向过程和面向对象二.类的引入三.类的定义1.定义和声明全部放在类体中,需要注意的是:2.声明与定义分离四.类的访问限定符及封装1.访问限定符2.封装五.类的作用域六...
    99+
    2024-04-02
  • C++ 再识类和对象
    目录类的6个默认成员函数构造函数1.概念2.特性隐式构造函数无参和全缺省的函数均为默认构造函数成员变量的命名风格补充析构函数1.概念2.特性c++编译器在对象生命周期结束时自动调用析...
    99+
    2024-04-02
  • C++类与对象的基础知识点详细分析
    目录一、什么是类和对象呢1、类的引入2、类的定义3、类的访问限定符4、类对象的储存方式5、this指针的特性二、类的六个默认成员函数详解1、构造函数2、析构函数一、什么是类和对象呢 ...
    99+
    2023-02-13
    C++类与对象知识点 C++类与对象关系
  • C++类与对象的重点知识点详细分析
    目录一、类的六个默认成员函数详解1、拷贝构造1.1 拷贝构造的引入及概念1.2 拷贝构造函数的特征2、赋值运算符重载2.1 运算符重载2.2 赋值运算符重载3、普通对象取地址4、co...
    99+
    2023-02-13
    C++类与对象知识点 C++类与对象关系
  • C++全面精通类与对象
    目录运算符重载运算符复用前置后置运算符constC++ 的IO流初始化列表explicit 关键字运算符重载 C++语法设计很巧妙,比如运算符重载一个 > bool opera...
    99+
    2024-04-02
  • C++类与对象实例分析
    这篇“C++类与对象实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C++类与对象实例分析”文章吧。运算符重载C++语...
    99+
    2023-06-30
  • C++类与对象之日期类的实现
    目录1. 实现前的铺垫2. 日期类的实现2.1 日期+=天数2.2 日期-=天数2.3 日期-天数2.4 日期+天数2.5 前置++2.6 后置++2.7 前置–2.8 后置–2.9...
    99+
    2024-04-02
  • C++类与对象的详细说明
    目录类的引入类的定义1、声明和定义全部放在类体中2、声明放在头文件,定义放在源文件中类的访问限定符号及封装访问限定符封装类的实例化类对象模型this指针this指针的特性总结类的引入...
    99+
    2024-04-02
  • C++浅析类与对象的基础
    目录面向过程和面向对象类的引入访问限定符封装类的作用域类的实例化面向过程和面向对象 类和对象是 C++ 的核心特性 我们之前的C语言就属于面向过程,关注过程,分析求解问题的步骤再通过...
    99+
    2024-04-02
  • C++类与对象的示例分析
    这篇文章主要介绍了C++类与对象的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。类的引入在引入类之前,先来回忆一下C语言中的结构体。结构体是一种自定义类型,可以在其中...
    99+
    2023-06-29
  • C++浅析类与对象基础点
    目录认识类和对象访问限定符this指针认识类和对象 C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。 C++是基于面向对象的,关注的是对象,将一件事...
    99+
    2024-04-02
  • 【C++漂流记】一文搞懂类与对象的封装
    本篇文章主要说明了类与对象中封装的有关知识,包括属性和行为作为整体、访问权限、class与struct的区别、成员属性的私有化,希望这篇文章可以帮助你更好的了解类与对象这方面的知识。 ...
    99+
    2023-09-17
    c++ 前端 开发语言
  • C++中的类与对象深度解析
    目录初始化列表引论初始化列表explicit关键字引论explicit关键字使用static成员 友元引论友元内部类基础概念内部类的使用补充析构顺序例题总结初始化列表 引论...
    99+
    2024-04-02
  • C++类与对象的详细说明2
    目录类的默认成员函数构造函数概念特性析构函数概念特性拷贝构造函数概念特征赋值运算符重载运算符重载赋值运算符重载取地址及const取地址操作符重载总结类的默认成员函数 每个类中,如果不...
    99+
    2024-04-02
  • C++中类与对象的示例分析
    这篇文章将为大家详细讲解有关C++中类与对象的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。前言:C 语言是面向过程的,关注的是过程,分析出求解的步骤,通过函数逐步调用解决问题。C++是基于面向对...
    99+
    2023-06-22
  • C++中的类与对象实例分析
    今天小编给大家分享一下C++中的类与对象实例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。初始化列表引论//初始化列表的...
    99+
    2023-06-29
  • C++类与对象基础点有哪些
    本文小编为大家详细介绍“C++类与对象基础点有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++类与对象基础点有哪些”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。认识类和对象C语言是面向过程的,关注的是过...
    99+
    2023-07-02
  • 【C++类和对象】类有哪些默认成员函数呢?(下)
    文章目录 一、类的6个默认成员函数二、日期类的实现2.1 运算符重载部分2.2 日期之间的运算2.3 整体代码1.Date.h部分2. Date.cpp部分 三. const成员函数...
    99+
    2023-09-06
    c++ 开发语言
  • 【C++心愿便利店】No.8---C++之重识类和对象
    文章目录 前言一、再谈构造函数二、static成员三、友元四、内部类五、匿名对象六、再次理解类和对象 前言 👧个人主页:@小沈YO. 😚小编介绍:欢...
    99+
    2023-10-27
    c++ 开发语言
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作