当前位置:首页 » 《随便一记》 » 正文

【C++】类与对象(三)—运算符重载|const成员函数|取地址及const取地址操作符重载

19 人参与  2024年02月06日 13:01  分类 : 《随便一记》  评论

点击全文阅读


在这里插入图片描述

前言
运算符重载,自增自减运算符重载,const成员函数,取地址及const取地址操作符重载


文章目录

一、运算符重载自增和自减运算符重载 二、const 成员函数三、取地址及const取地址操作符重载(了解即可)

一、运算符重载

运算符重载允许重新定义类对象的运算符行为。通过运算符重载,你可以使自定义类型的对象与内置类型一样,使用各种运算符进行操作,从而提高代码的可读性和灵活性。

语法:

//函数名:关键字operator后面接需要重载的运算符符号。//函数原型:返回值类型 operator操作符(参数列表)ReturnType operator+(参数) {        // 重载的 + 运算符的实现        // 返回类型可以是任何合适的类型    }

运算符重载可以被重载成类的成员函数,也可以被重载成全局函数。重载成员函数形式的赋值运算符在使用时通过成员访问方式调用,而重载全局函数形式的赋值运算符则直接通过函数名调用。
1. 成员函数形式:

class MyClass {public:    // 成员函数形式的赋值运算符重载    MyClass& operator=(const MyClass& other) {        // 实现赋值操作        // 返回当前对象的引用        if (this != &other) {            // 实现赋值操作,例如深拷贝资源        }        return *this;    }};// 调用MyClass obj1, obj2;obj1 = obj2;

在成员函数形式中,运算符重载是通过对象的成员访问方式调用的。左侧的对象(obj1)成为调用对象,右侧的对象(obj2)成为参数传递给成员函数。


2. 全局函数形式:
在全局函数的形式下,函数的参数中不会隐含this指针,因此要传两个参数。

class MyClass {    // MyClass 的声明};// 全局函数形式的赋值运算符重载MyClass& operator=(MyClass& obj1, const MyClass& obj2) {    // 实现赋值操作    // 返回第一个对象的引用    if (&obj1 != &obj2) {        // 实现赋值操作,例如深拷贝资源    }    return obj1;}// 调用MyClass obj1, obj2;obj1 = obj2;

在全局函数形式中,运算符重载是通过函数名直接调用的。左侧的对象(obj1)成为函数的第一个参数,右侧的对象(obj2)成为函数的第二个参数。


注意:

不能通过连接其他符号来创建新的操作符:比如operator@重载操作符必须有一个类类型参数用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不 能改变其含义作为成员函数重载时,第一个参数为隐藏的this.* :: sizeof ?: . 这5个运算符不能重载。.* 用于访问类成员指针的操作符。

自增和自减运算符重载

前置和后置自增自减运算符的区分是通过参数列表的一个标识符来实现的。具体来说,前置版本没有任何参数,而后置版本有一个额外的(但不使用)int参数。

这里以自增为例:

重载前置自增运算符    ReturnType operator++(){}重载后置自增运算符    ReturnType operator++(int){}

前置和后置自增的实现:

前置自增运算符重载:

class MyClass {private:    int value;public:    // 重载前置自增运算符    MyClass& operator++() {        ++value;        return *this;    }};

后置自增运算符重载:

class MyClass {private:    int value;public:    // 重载后置自增运算符    MyClass operator++(int) {        MyClass temp = *this; // 保存原始值        ++value;             // 执行自增操作        return temp;         // 返回原始值    }};

注意:

前置自增运算符返回引用,使得可以对同一对象连续进行自增操作。后置自增运算符通过返回原始值的副本,再执行自增操作,以允许保留原始值。

二、const 成员函数

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

以日期类为例:
我们创建一个对象,同时加const修饰,变成常量对象。

class Date {private:int _year;int _month;int _day;public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}void Print() {cout << _year << "/" << _month << "/" << _day << endl;}};int main() {//d1 被声明为常量对象,不可修改const Date d1(2024, 1, 31);//报错:“void Date::Print(void)”: 不能将“this”指针从“const Date”转换为“Date &”//d1.Print(); return 0;}

当我们调用成员函数Print()时,编译器会报错,这是因为在通过对象调用成员函数时,this指针被隐式传参,d1是只读不可修改,但在Print()又没有办法对this指针进行限制,所以会出现权限放大的情况。权限只可以平移,缩小,但是不能放大。

//Date成员函数void Print() {cout << _year << "/" << _month << "/" << _day << endl;}Date d1(2024, 1, 31);//d1 是可读可修改,在Print()内同样是可读可修改的,这是权限平移d1.Print();//---------------------------------------------------------------------void Print(const int a) {cout << _year << "/" << _month << "/" << _day << endl;}Date d1(2024, 1, 31);int a = 5;//在Print()中a不可被修改,这是权限缩小d1.Print(a);

所以提出了const成员函数的概念。在函数名后加const实际上限制了this指针。

//在函数名后面加上constvoid Print() const {cout << _year << "/" << _month << "/" << _day << endl;}//实际上是对this的修饰void Print(/*const Date* this*/) {cout << _year << "/" << _month << "/" << _day << endl;}

另外,如果一个类有两个版本的成员函数,一个是const版本,一个是非const版本,它们可以根据需要被const和非const对象调用。这实际上是函数重载


思考这些问题:

const对象可以调用非const成员函数吗?非const对象可以调用const成员函数吗?const成员函数内可以调用其它的非const成员函数吗?非const成员函数内可以调用其它的const成员函数吗?

const对象可以调用非const成员函数吗?

不可以。const 对象只能调用 const 成员函数,因为 const 对象的目的是确保对象的状态不被修改。调用非 const 成员函数会导致编译错误。

非const对象可以调用const成员函数吗?

是的。非 const 对象可以调用 const 成员函数。这是因为 const 成员函数对对象的状态有只读的访问权限,不会修改对象的成员变量。因此,非 const 对象可以安全地调用 const 成员函数。

const成员函数内可以调用其他的非const成员函数吗?

是的。在 const 成员函数内部,可以调用其他非 const 成员函数,只要这些非 const 成员函数不会修改对象的成员变量。这是因为 const 成员函数对对象的状态有限制,但它可以调用其他不会修改状态的函数。

非const成员函数内可以调用其他的const成员函数吗?

是的。非 const 成员函数内部可以调用 const 成员函数,因为非 const 成员函数对对象的状态没有限制,可以进行读写操作。因此,非 const 成员函数可以调用 const 成员函数,而不会导致问题。

三、取地址及const取地址操作符重载(了解即可)

Date* operator&(){return this;}const Date* operator&()const{return this;}

取地址及const取地址操作符重载也是默认成员函数,不需要显式提供,编译器可以自己生成。

class Date{private:int _year;int _month;int _day;public:Date(int year, int month, int day) {_year = year;_month = month;_day = day;}Date* operator&(){return this;}const Date* operator&()const{return this;}};int main() {Date a(2024, 1, 31);const Date b(2024, 1, 3);cout << &a << endl;cout << &b << endl;return 0;}

在这里插入图片描述


在这里插入图片描述
如果你喜欢这篇文章,点赞?+评论+关注⭐️哦!
欢迎大家提出疑问,以及不同的见解。


点击全文阅读


本文链接:http://m.zhangshiyu.com/post/67563.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最新文章

  • 女士的玩具推文_杜小灵白月光杜雪必读文_小说后续在线阅读_无删减免费完结_
  • 女儿要给我养老,我却反手把她告上法庭每日分享_林梦王浩养老一口气完结_小说后续在线阅读_无删减免费完结_
  • 闻妻有两意(林鹿小柿子)_闻妻有两意
  • 我的死党是刘秀?这皇位我不篡了(李哲王莽)全书免费_(李哲王莽)我的死党是刘秀?这皇位我不篡了后续(李哲王莽)
  • 逃荒路末世女王带着空间养儿女(周铁山王寡妇阿蛮)_逃荒路末世女王带着空间养儿女(周铁山王寡妇阿蛮)
  • 霍远凡肖灿续集(霍远凡肖灿)章节前文+全书阅读(丈夫逼我流产,我以死谢罪)最新连载
  • 老公给我13.14亲密付,我堕胎再婚后他悔疯了每日分享_苏暖顾川林晚晚超长版_小说后续在线阅读_无删减免费完结_
  • (白瑶,李玄胤,冰冷)白瑶,李玄胤,冰冷小说(九尾渡红尘)无套路无弹窗全部章节列表
  • (此去经年无故人)南初陆南城:结局+番外精品选集起点章节+阅读即将发布预订
  • 沈凝夏叶晚怡附加完整在线阅读(归雁不栖故人枝)最近更新列表
  • 剧情人物是时初,白浩雄的玄幻言情小说《召诸神,踏万界,天命帝女逆乾坤》,由网络作家&ldquo;海鸥&rdquo;所著,情节扣人心弦,本站TXT全本,欢迎阅读!本书共计381345字,185章节,:结局+番外免费品鉴:结局+番外评价五颗星
  • 凤青禾,江明远,***枢小说(别人修仙我捡漏,卷王们破防了)最近更新(凤青禾,江明远,***枢)整本无套路阅读

    关于我们 | 我要投稿 | 免责申明

    Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1