当前位置: 首页 > news >正文

0903 C++类的运算符重载、静态成员与继承

Part 1.梳理思维导图

一.运算符重载

1.运算符重载的作用

使原本只能对基本数据类型生效的运算符,在重载后,满足可以对构造类型数据生效。

2.关系运算符重载

        a.关系运算符种类

>         >=         <         <=         ==         !=

        b.分析参数

表达式:左值 关系运算符 右值

左值:只能为左值

右值:可以为左值,也可以为右值

返回值:bool(ture or false)

        c.函数格式

成员函数:bool operator关系运算符(const 类名 &R) const

全局函数:bool operator关系运算符(const类名 &L,const 类名 &R)

        d.分析

因为返回值使bool类型,所以函数头为bool;

operator关系运算符为函数名,由于成员函数的实现方式是左值调用函数参数为右值,所以参数只有右值;

由于不改变右值,所以该成员函数后面加上const,使其成为常成员函数;

全局函数中实现方式为一个函数调用左值和右值就行关系运算,所以参数为两个,因为关系运算不改变参数值,所以加const

        e.例子

以关系运算符>为例,当需要全局函数实现时,需要在类内添加友元

#include <iostream>using namespace std;class num
{
//    friend const num operator+(const num &L,const num &R);
//    friend bool operator>(const num &L,const num &R);
private:int a;int b;
public:num(){}num(int a,int b):a(a),b(b){}const num operator+(const num &R) const{num temp;temp.a = a + R.a;temp.b = b + R.b;return temp;}//成员函数实现bool operator>(const num &R) const{if(a > R.a && b < R.b)return true;elsereturn false;}void show(){cout << "a = " << a << " b = " << b << endl;}
};//const num operator+(const num &L,const num &R)
//{
//    num temp;
//    temp.a = L.a + R.a;
//    temp.b = L.b + R.b;
//    return temp;
//}//全局函数实现,需要在类内添加友元
//bool operator>(const num &L,const num &R)
//{
//    if(L.a > R.a && L.b < R.b)
//        return true;
//    else
//        return false;
//}ostream & operator<<(ostream &cout,const num &n)
{cout << n.a << " " << n.b << endl;return cout;
}istream & operator>>(istream &cin,num &n)
{cin >> n.a >> n.b;return cin;
}int main()
{num n1(2,3);num n2(3,4);num n3 = n1+n2;n3.show();if(n1 > n2)cout << "n1 > n2" << endl;elsecout << "n1 < n2" << endl;return 0;
}

3.赋值运算符重载

        a.赋值运算符种类

+=        -=        *=        /=        %=

        b.分析参数

表达式:左值 赋值运算符 右值(a += b)

左值:只能为左值

右值:可以为左值,也可以为右值

返回值:自身的引用

        c.函数格式

成员函数:类名 &operator赋值运算符(const 类名 &R)

全局函数:类名 &operator赋值运算符(类名 &L,const 类名 &R)

        d.分析

因为成员函数和全局函数返回的均是左值的引用,所以函数的返回值类型为 类名 &;

成员函数实现方式时将右值作为参数给左值调用,所以只有右值为参数;

全局变量需要二者均为参数,但是由于右值会发生变化,所以只有左值加const;

        e.例子
#include <iostream>using namespace std;class num
{
//    friend const num operator+(const num &L,const num &R);
//    friend bool operator>(const num &L,const num &R);
//    friend num & operator+=(num &L,const num &R);private:int a;int b;
public:num(){}num(int a,int b):a(a),b(b){}const num operator+(const num &R) const{num temp;temp.a = a + R.a;temp.b = b + R.b;return temp;}bool operator>(const num &R) const{if(a > R.a && b < R.b)return true;elsereturn false;}//成员函数实现num &operator+=(const num &R){a = a + R.a;b = b + R.b;return *this;}void show(){cout << "a = " << a << " b = " << b << endl;}
};//const num operator+(const num &L,const num &R)
//{
//    num temp;
//    temp.a = L.a + R.a;
//    temp.b = L.b + R.b;
//    return temp;
//}//bool operator>(const num &L,const num &R)
//{
//    if(L.a > R.a && L.b < R.b)
//        return true;
//    else
//        return false;
//}//全局函数实现
//num & operator+=(num &L,const num &R)
//{
//    L.a = L.a + R.a;
//    L.b = L.b + R.b;
//    return  L;
//}int main()
{num n1(2,3);num n2(3,4);num n3 = n1+n2;n3.show();//    if(n1 > n2)
//        cout << "n1 > n2" << endl;
//    else
//        cout << "n1 < n2" << endl;n1 += n2 += n3;n1.show();n2.show();n3.show();return 0;
}

4.自增自减运算符

        a.自增自减运算符种类

++(前自增和后自增)        --(前自减和后自减)

        b.分析参数

表达式:前:自增自减运算符 值(++a)        后:值 自增自减运算符(a++)

值:只能为左值

返回值:前:自身的引用        后:右值

        c.函数格式

成员函数:前:类名 &operator自增自减运算符()

                  后:const 类名 operator自增自减运算符(int )

全局函数:前:类名 &operator自增自减运算符(类名 &O)

                  后:const 类名 operator自增自减运算符(类名 &O,int)

        d.前自增和后自增的区别

前自增返回段值是一个左值,可以继续被使用于函数,而后自增返回的是一个右值,不能被继续适用于函数

        e.分析

因为自增自减函数只需要调用自己,所以成员函数内没参数,全局函数内参数为自己;

前自增函数和后自增函数都是一样的引用,为了能满足函数重载,使函数使用的更方便,在后自增函数中增加一个哑元,使其满足函数重载的定义(参数个数不同或者参数类型不同);

前自增的返回值类型是类名 &(类的引用)是个左值,后自增返回的是类名(类的右值返回)是个右值;

        f.例子

因为后自增是返回没自增前的值,所以需要定义一个新的临时类成员,用于返回

#include <iostream>using namespace std;class num
{
//    friend const num operator+(const num &L,const num &R);
//    friend bool operator>(const num &L,const num &R);
//    friend num & operator+=(num &L,const num &R);
//    friend num &operator++(num &L);
//    friend const num operator++(num &L,int);
private:int a;int b;
public:num(){}num(int a,int b):a(a),b(b){}const num operator+(const num &R) const{num temp;temp.a = a + R.a;temp.b = b + R.b;return temp;}bool operator>(const num &R) const{if(a > R.a && b < R.b)return true;elsereturn false;}num &operator+=(const num &R){a = a + R.a;b = b + R.b;return *this;}//成员函数实现前自增num &operator++(){a++;b++;return *this;}//成员函数实现后自增const num operator++(int){num temp;temp.a = a++;temp.b = b++;return temp;}void show(){cout << "a = " << a << " b = " << b << endl;}
};//const num operator+(const num &L,const num &R)
//{
//    num temp;
//    temp.a = L.a + R.a;
//    temp.b = L.b + R.b;
//    return temp;
//}//bool operator>(const num &L,const num &R)
//{
//    if(L.a > R.a && L.b < R.b)
//        return true;
//    else
//        return false;
//}//num & operator+=(num &L,const num &R)
//{
//    L.a = L.a + R.a;
//    L.b = L.b + R.b;
//    return  L;
//}//全局函数实现前自增
//num &operator++(num &L)
//{
//    ++L.a;
//    ++L.b;
//    return L;
//}//全局函数实现后自增
//const num operator++(num &L,int)
//{
//    num temp;
//    temp.a = L.a++;
//    temp.b = L.b++;
//    return temp;
//}int main()
{num n1(2,3);num n2(3,4);num n3 = n1+n2;n3.show();//    if(n1 > n2)
//        cout << "n1 > n2" << endl;
//    else
//        cout << "n1 < n2" << endl;//    n1 += n2 += n3;
//    n1.show();
//    n2.show();
//    n3.show();cout << "++++++++++++++++++" << endl;n1.show();++n1;n1.show();cout << "++++++++++++++++++" << endl;n1.show();n2.show();n2 = n1++;n1.show();n2.show();return 0;
}

5.插入提取运算符重载

        a.插入提取运算符类型

<<插入运算符        >>提取运算符

        b.分析参数

表达式:左值 插入提取运算符 右值(cout << a)

左值:istream类的cin 或者 ostream类的cout

右值:类成员

返回值:iostram类的cin或者cout的引用

        c.函数格式

成员函数:因为返回值类型为iostram类,调用的函数为该类的函数,不适合在右值类内创建成员函数

全局函数:cout:ostream &operator<<(ostream &cout,const 类名 &a)

                  cin:istream &operator>>(istream &cin,类名 &a)

        d.例子
#include <iostream>using namespace std;class num
{
//    friend const num operator+(const num &L,const num &R);
//    friend bool operator>(const num &L,const num &R);
//    friend num & operator+=(num &L,const num &R);
//    friend num &operator++(num &L);
//    friend const num operator++(num &L,int);friend ostream & operator<<(ostream &cout,const num &n);friend istream & operator>>(istream &cin,num &n);
private:int a;int b;
public:num(){}num(int a,int b):a(a),b(b){}const num operator+(const num &R) const{num temp;temp.a = a + R.a;temp.b = b + R.b;return temp;}bool operator>(const num &R) const{if(a > R.a && b < R.b)return true;elsereturn false;}num &operator+=(const num &R){a = a + R.a;b = b + R.b;return *this;}num &operator++(){a++;b++;return *this;}const num operator++(int){num temp;temp.a = a++;temp.b = b++;return temp;}void show(){cout << "a = " << a << " b = " << b << endl;}
};//const num operator+(const num &L,const num &R)
//{
//    num temp;
//    temp.a = L.a + R.a;
//    temp.b = L.b + R.b;
//    return temp;
//}//bool operator>(const num &L,const num &R)
//{
//    if(L.a > R.a && L.b < R.b)
//        return true;
//    else
//        return false;
//}//num & operator+=(num &L,const num &R)
//{
//    L.a = L.a + R.a;
//    L.b = L.b + R.b;
//    return  L;
//}//num &operator++(num &L)
//{
//    ++L.a;
//    ++L.b;
//    return L;
//}//const num operator++(num &L,int)
//{
//    num temp;
//    temp.a = L.a++;
//    temp.b = L.b++;
//    return temp;
//}//全局函数实现<<
ostream & operator<<(ostream &cout,const num &n)
{cout << n.a << " " << n.b << endl;return cout;
}//全局函数实现>>
istream & operator>>(istream &cin,num &n)
{cin >> n.a >> n.b;return cin;
}int main()
{num n1(2,3);num n2(3,4);num n3 = n1+n2;n3.show();//    if(n1 > n2)
//        cout << "n1 > n2" << endl;
//    else
//        cout << "n1 < n2" << endl;//    n1 += n2 += n3;
//    n1.show();
//    n2.show();
//    n3.show();cout << "++++++++++++++++++" << endl;n1.show();++n1;n1.show();cout << "++++++++++++++++++" << endl;n1.show();n2.show();n2 = n1++;n1.show();n2.show();return 0;
}

二.静态成员

1.目的

申请静态成员是让每个类的这个静态成员实现共享

2.注意事项

静态成员不能在类内初始化,只能在类外初始化

静态成员函数只能访问静态成员

3.格式

class 类名
{int a;static 数据类型 变量名; // 静态数据成员static 返回值类型 函数名(形参列表)// 静态成员函数{ }};数据类型 类名::变量名 = 初始化;

4.例子

该函数为模拟银行存储,balance为余额,rate为利率,静态成员利率会在函数外改变,并使每一个账户成员利率一起改,静态函数static double getrate()只能调用静态成员rate,static double getmenory(Bankaccent &accent)静态函数为了调用非静态成员balance,只能调用类对象再调用

#include <iostream>using namespace std;class Bankaccent
{
private:double balance;static double rate;
public:Bankaccent(){}Bankaccent(double balance):balance(balance){};static double getrate(){return rate;}static void setrate(double setrate){rate = setrate;}static double getmenory(Bankaccent &accent){return accent.balance*(1+rate);}};double Bankaccent::rate = 0.05;int main()
{Bankaccent accent1(1000);cout << Bankaccent::getrate() << endl;Bankaccent::setrate(0.06);cout << Bankaccent::getrate() << endl;cout << Bankaccent::getmenory(accent1) << endl;return 0;
}

三.继承

1.目的

1.实现代码的复用性(重用性)

2.建立父类和子类之间的联系

3.通过继承 实现多态

2.继承的概念

在已有的一个类基础上,衍生出一个新的类,此为继承

被继承的类成为父类

继承的类成为子类

子类拥有父类所有成员和成员函数

3.格式

class 类名 : 继承方式 类名
{子类的拓展;
};

4.继承方式

1.public:父类的成员继承方式按原继承方式保存。原父类中,public,protected类可以访问private子类不能访问

2.protected:父类的成员继承方式按原继承方式为public改为protected保存,其他继承方式不变。原父类中,public,protected类可以访问private子类不能访问

3.private:父类的成员继承方式全按private继承方式保存。原父类中,public,protected类可以访问private子类不能访问

Part 2.程序

搭建一个货币的场景,创建一个名为 RMB 的类,该类具有整型私有成员变量 yuan(元)、jiao(角)和 fen(分),并且具有以下功能:

(1)重载算术运算符 + 和 -,使得可以对两个 RMB 对象进行加法和减法运算,并返回一个新的 RMB 对象作为结果。

(2)重载关系运算符 >,判断一个 RMB 对象是否大于另一个 RMB 对象,并返回 true 或 false。

(3)重载前置减减运算符 --,使得每次调用时 RMB 对象的 yuan、jiao 和 fen 分别减 1

(4)重载后置减减运算符 --,使得每次调用时 RMB 对象的 yuan、jiao 和 fen 分别减 1

(5)另外, RMB 类还包含一个静态整型成员变量 count,用于记录当前已创建的 RMB 对象的数量。每当创建一个新的 RMB 对象时,count 应该自增 1;每当销毁一个 RMB 对象时,count 应该自减 1。

要求,需要在main 函数中测试上述RMB 类的功能

#include <iostream>using namespace std;class RMB
{
private:int yuan;int jiao;int fen;static int count;
public:RMB(){countplus();}RMB(int yuan,int jiao,int fen):yuan(yuan),jiao(jiao),fen(fen){countplus();}RMB(const RMB& other):yuan(other.yuan),jiao(other.jiao),fen(other.fen){countplus();}~RMB(){countdecrease();}const RMB operator+(const RMB &R){RMB temp;temp.yuan = yuan+R.yuan;temp.jiao = jiao+R.jiao;temp.fen = fen+R.fen;return temp;}const RMB operator-(const RMB &R){RMB temp;temp.yuan = yuan-R.yuan;temp.jiao = jiao-R.jiao;temp.fen = fen-R.fen;return temp;}bool operator>(const RMB &R){if(yuan > R.yuan)return true;elsereturn false;}RMB &operator--(){--yuan;--jiao;--fen;return *this;}const RMB operator--(int){RMB temp;temp.yuan = yuan--;temp.jiao = jiao--;temp.fen = fen--;return temp;}static void countplus(){count++;}static void countdecrease(){count--;}static int countshow(){return count;}void show(){cout << yuan << " " << jiao << " " << fen << endl;}
};int RMB::count = 0;int main()
{{cout << RMB::countshow() << endl;RMB r1(100,99,88);cout << RMB::countshow() << endl;RMB r2(55,101,76);cout << RMB::countshow() << endl;cout << "算数运算符+" << endl;r1 = r1+r2;r1.show();cout << "算数运算符-" << endl;r1 = r1-r2;r1.show();cout << "关系运算符>" << endl;bool a = r1 > r2;cout << a << endl;cout << "前自减运算符--" << endl;--r1;r1.show();cout << "后自减运算符--" << endl;RMB r3 = r2--;r3.show();r2.show();}cout << RMB::countshow() << endl;return 0;
}

http://www.xdnf.cn/news/1448155.html

相关文章:

  • 前端-安装VueCLI
  • 【ARM嵌入式汇编基础】-数据处理指令(三)
  • OpenHarmony Ability“全家桶”彻底拆解:从UIAbility到ExtensionAbility一文说清楚
  • LeetCode 1537.最大得分
  • 残差连接的概念与作用
  • 蓝桥杯算法之基础知识(6)
  • Netty从0到1系列之Channel
  • 【 线段树】P12347 [蓝桥杯 2025 省 A 第二场] 栈与乘积|普及+
  • 基于 HTML、CSS 和 JavaScript 的智能图像灰度直方图分析系统
  • HTML全屏功能实现汇总
  • npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR!
  • 求单源最短路(Dijkstra 算法-迪杰斯特拉算法,SPFA)
  • 【Unity基础】两个关于UGUI中Text对非英文字体支持的问题
  • SpringAI应用开发面试全流程:技术原理、架构优化与企业场景解析
  • 复写零(双指针)
  • JavaScript学习最后一章节(小练习)
  • 如何解决虚拟机网络连接问题:配置固定 IP 篇
  • Spring Authorization Server 1.5.2 使用YML配置的方式,最常用法总结
  • 【算法--链表】141.环形链表(通俗讲解链表中是否有环)
  • 分布式AI算力系统番外篇-----超体的现世《星核》
  • 强化学习中的模仿学习是什么?
  • 相关性分析与常用相关系数
  • react的 hooks 是如何存储的
  • HTML第七课:发展史
  • Streamlit 数据看板模板:非前端选手快速搭建 Python 数据可视化交互看板的实用工具
  • 如何画时序图、流程图
  • android集成unity后动态导入 assetsBundle
  • Android创建demo脚本
  • CSS中使用 HSL(Hue, Saturation, Lightness) 动态生成色值
  • Linux 对目录授予用户读写权限的方法