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

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

目录

一、前言

二、const成员函数 

🍎const修饰类的成员函数 

💦问题1 

💦问题2

💦针对const成员函数的常考面试题(重点!!)

🍐取地址及const取地址操作符重载

三、共勉


一、前言

   在我们前面学习的中,我们会定义成员变量成员函数,这些我们自己定义的函数都是普通的成员函数,但是如若我们定义的类里什么也没有呢?是真的里面啥也没吗?如下:

class Date {};

  如果一个中什么成员都没有,简称为空类。空类中什么都没有吗?并不是的任何一个类在我们不写的情况下,都会自动生成6个默认成员函数。


【默认成员函数概念】:用户没有显式实现,编译器会生成的成员函数称为默认成员函数
c++ const函数,C++,c++,开发语言,linux,服务器,数据结构,算法

⭐其中上次的博客已经详细的讲解了构造函数&&析构函数的使用方法与拷贝构造函数和赋值运算符重载,所以本次博客将继续深度的讲解const成员函数问题

二、const成员函数 

🍎const修饰类的成员函数 

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

💦问题1 

 假如我现在有一个日期类,并且有如下的Func函数即调用情况:

class Date
{
public:
	//构造函数
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Printf()
	{
		cout << _year << "年" << _month << "月" << _day << "日" << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

void Func(const Date& d)
{
	d.Printf();
}

int main()
{
	Date d1(2023, 11, 1);
	d1.Printf();
	Date d2(2023, 11, 2);
	Func(d2);
	return 0;
}

此时却出现了报错,这是为什么呢?

c++ const函数,C++,c++,开发语言,linux,服务器,数据结构,算法

很明显,这里Func函数d的调用Print()出错了,而d1调用Print()却没出错,为何呢?

这里涉及到权限问题。我们先把实际调用过程中,隐含的this指针写出来:
如果对 this指针不了解的朋友可以看这篇博客:this 指针详解

c++ const函数,C++,c++,开发语言,linux,服务器,数据结构,算法
Print()函数里的const修饰this本身,this不能修改,但是this可以初始化,接着我们要搞清楚&d1和&d的类型分别是啥:

  • &d1:Date*
  • &d:const Date*
  1. Date*传给Date* const没有问题,都是可读也可修改,所以d1调用Print()不会出错
  2. 而const Date* 指向的内容不能被修改,可是当它传给Date*时就出错了,因为Date*是可以修改的,这里传过去会导致权限放大。所以当然d调用Print()函数报错。
c++ const函数,C++,c++,开发语言,linux,服务器,数据结构,算法


 

⭐解决办法: 
加上const去保护this指向的内容,也就是在Date*的前面加上const:

void Print(const Date* const this)
{
	cout << _year << "年" << _month << "月" << _day << "日" << endl;
}

但是这里又不能之间加上const,因为this指针是隐含的,你不能显示的将const写出来。因此,C++为了解决此问题,允许在函数后面加上const以达到刚才的效果:
 

void Print() const// 编译器默认处理成:void Print(const Date* const this)
{
	cout << _year << "-" << _month << "-" << _day << endl;
}

此时我const Date*传给const Date*就是权限不变,自然不会出错了,同样我Date*传给const Date*就是权限缩小也不会有问题。因为权限不能放大,只能缩小或不变。

正确的代码:

class Date
{
public:
	//构造函数
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Printf()  const     // void Printf(Date* const this)
	{
		cout << _year << "年" << _month << "月" << _day << "日" << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

void Func(const Date& d)
{
	d.Printf();   // d.Printf(&d);
}

int main()
{
	Date d1(2023, 11, 1);
	d1.Printf();           // d1.Printf(&d);
	Date d2(2023, 11, 2);
	cout << endl;
	Func(d2);
	return 0;
}

c++ const函数,C++,c++,开发语言,linux,服务器,数据结构,算法


 

 💦问题2

假如我们遇到如下,自定义类型的比较情况:

class Date
{
public:
	//构造函数
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	bool operator<(const Date& d)
	{
		if (_year < d._year ||
			_year == d._year && _month < d._month ||
			_year == d._year && _month == d._month && _day < d._day)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1(2023, 11, 1);
	const Date d2(2023, 11, 2);
	cout << endl;
	d1 < d2;
	d2 < d1;
	return 0;
}

此时却出现了报错,这是为什么呢?

c++ const函数,C++,c++,开发语言,linux,服务器,数据结构,算法

c++ const函数,C++,c++,开发语言,linux,服务器,数据结构,算法

  • 首先对于第一个比较来说d1d2都是权限的保持
  • 接着对于第二个比较来说d1传递过去是权限的缩小,本来是可以修改了,现在不能修改;d2传递过去就变成了【权限的放大】,原本的d2const,但是this指针并没有加[const]做修饰,所以就造成了【权限方法】的问题

c++ const函数,C++,c++,开发语言,linux,服务器,数据结构,算法

        那要怎么去做一个修改呢?此时就可以使用到我们上面所讲到的【const成员函数】,为当前的隐藏形参this 加上一个const做修饰,此时就可以做到【权限保持】

bool operator<(const Date& d) const

 💦针对const成员函数的常考面试题(重点!!)

问题1:const对象 可以调用 非const成员函数吗?

c++ const函数,C++,c++,开发语言,linux,服务器,数据结构,算法


        这个当然不可以。我们前面已经说过了,若 const对象去调用非const成员函数,会造成【权限放大】的现象,原本在类外const对象的内容是不可以修改的,但是到了函数内部却有可以修改了,这是不被允许的

 问题2:非const对象 可以调用 const成员函数吗?

c++ const函数,C++,c++,开发语言,linux,服务器,数据结构,算法


        这个当然是可以的。非const对象本身就是可读可写的,那在函数内部你要去修改或者不修改都不会有影响

 问题3:const成员函数内可以调用其它的非const成员函数吗?
c++ const函数,C++,c++,开发语言,linux,服务器,数据结构,算法

       

       不可以,const成员函数内部只能调用const成员函数。因为const成员函数内部的this指针已经具有常属性的,万一这个非const成员函数去修改了成员变量的内容就会出问题了

 问题4:非const成员函数内可以调用其它的const成员函数吗?

c++ const函数,C++,c++,开发语言,linux,服务器,数据结构,算法


       可以,权限缩小
 

🍐取地址及const取地址操作符重载

class Date
{
public:
    //取地址&重载
	Date* operator&()
	{
		return this;
	}
    //const取地址&重载
	const Date* operator&()const
	{
		return this;
	}
private:
	int _year;
	int _month;
	int _day;
};

当然,如果我们自己不写&重载,编译器也会默认生成,可以通过打印来看看:

c++ const函数,C++,c++,开发语言,linux,服务器,数据结构,算法

三、共勉

         以下就是我对【C++】类的默认成员函数----const成员函数的理解,如果有不懂和发现问题的小伙伴,请在评论区说出来哦,同时我还会继续更新对C++ 类和对象的理解,请持续关注我哦!!!  

c++ const函数,C++,c++,开发语言,linux,服务器,数据结构,算法

 文章来源地址https://www.toymoban.com/news/detail-850594.html

到了这里,关于【C++】类的默认成员函数----const成员函数(超详细解析)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • C++:类的六个默认成员函数

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

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

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

    2024年02月20日
    浏览(40)
  • 【C++初阶】类和对象——操作符重载&&const成员函数&&取地址重载&&日期类的实现

    ========================================================================= 个人主页点击直达: 小白不是程序媛 C++系列专栏: C++头疼记 ========================================================================= 目录   前言: 运算符重载 运算符重载  赋值运算符重载 前置++和后置++重载 const成员 取地址及cons

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

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

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

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

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

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

    2024年02月20日
    浏览(30)
  • 【C++初阶】五、类和对象(日期类的完善、流运算符重载函数、const成员、“&”取地址运算符重载)

    ========================================================================= 相关代码gitee自取 : C语言学习日记: 加油努力 (gitee.com)  ========================================================================= 接上期 : 【C++初阶】四、类和对象 (构造函数、析构函数、拷贝构造函数、赋值运算符重载函数)-CSD

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

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

    2024年04月17日
    浏览(36)
  • 【C++精华铺】5.C++类和对象(中)类的六个默认成员函数

    目录 1. 六个默认成员函数 2. 构造函数 2.1 概念 2.2 默认构造 2.2.1 系统生成的默认构造 2.2.2 自定义默认构造函数  2.3 构造函数的重载 3. 析构函数 3.1 概念  3.2 系统生成的析构函数  3.3 自定义析构函数 4. 拷贝构造 4.1 概念  4.2 默认生成的拷贝构造(浅拷贝)  4.3 自定义拷贝构

    2024年02月13日
    浏览(61)
  • C++从入门到精通——类的6个默认成员函数之赋值运算符重载

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

    2024年04月25日
    浏览(44)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包