C++基础11-类和对象之操作符重载1

总结:

1、运算符重载的本质是函数重载
2、运算符重载可分为成员函数重载全局函数重载(差一个参数)
3、运算符重载函数的参数至少有一个是类对象(或类对象的引用)
4、不可以被重载的操作符有:成员选择符(.) 成员对象选择符(.*) 
                                                 域解析操作符(::) 条件操作符(?:)
5、前置加加 可以连续使用 后置加加 不可以连续使用
6、前置加加(减减)的运算符重载和普通运算符重载一样后置加加(减减)的运算符重载需要加一个占位符
7、输入输出运算符重载定义为全局函数重载。因为成员函数重载会发生歧义
8、输入输出运算符重载借助输入输出流(ostream istream)
9、双目运算符就是有两个参数(+,-),单目运算符有一个参数(++,--)
10、重载的前置加加 Complex& operator++(Complex &c1)  //返回引用的目的是使用连续前置加加
       重载的后置加加 const Complex& operator++(Complex &c1, int) 
                                  //加const的原因是后置加加不能连续使用
11、右移操作符重载:friend ostream& operator<<(ostream &os, Complex &c);
                    ostream& operator<<(ostream &os)  //c1.operator<<(cout)
                    { 
                        os << "(" << this->a << "," << this->b << "i)";
                        return os;
                    }
     左移操作符重载:friend istream& operator>>(istream &is, Complex &c);
                    istream& operator>>(istream &is, Complex &c)
                    {
                        cout << "a:";
                        is >> c.a;
                        cout << "b:";
                        is >> c.b;
                        return is;
                    }
12、若某函数中类想引用私有成员,则将此函数在这个类中声明为友元函数

13、除了赋值号(=)外,基类中被重载的操作符都将被派生类继承

1、操作符重载格式

重载函数的一般格式如下:

函数类型 operator 运算符名称(形参表列) {

         重载实体;

}

operator 运算符名称 在一起构成了新的函数名。比如

const Complex operator+(const Complex &c1,const Complex &c2);

我们会说,operator+ 重载了重载了运算符+。

2、重载规则

 

4.10.2 重载规则

(1)C++不允许用户自己定义新的运算符,只能对已有的 C++运算符进行重载。

例如,有人觉得 BASIC 中用“* *”作为幂运算符很方便,也想在 C++中将“**”定义为幂运算符,用“3**5”表示 35,这是不行的。

(2)C++允许重载的运算符

C++中绝大部分运算符都是可以被重载的。

不能重载的运算符只有 4 个:成员选择符(.) 成员对象选择符(.*)   域解析操作符(::) 条件操作符(?:)

前两个运算符不能重载是为了保证访问成员的功能不能被改变,域运算符合sizeof 运算符的运算对象是类型而不是变量或一般表达式,不具备重载的特征。

 

3)重载不能改变运算符运算对象(即操作数)的个数。

如,关系运算符“>”和“<”等是双目运算符,重载后仍为双目运算符,需要两 个参数。运算符”+“,”-“,”*“,”&“等既可以作为单目运算符,也可以作为双 目运算符,可以分别将它们重载为单目运算符或双目运算符。

4)重载不能改变运算符的优先级别。

例如”*“和”/“优先级高于”+“和”-“,不论怎样进行重载,各运算符之间的优先级不会改变。有时在程序中希望改变某运算符的优先级,也只能使用加括号的方法 强制改变重载运算符的运算顺序。

(5)重载不能改变运算符的结合性。

如,复制运算符”=“是右结合性(自右至左),重载后仍为右结合性。

(6)重载运算符的函数不能有默认的参数

否则就改变了运算符参数的个数,与前面第(3)点矛盾。

(7)重载的运算符必须和用户定义的自定义类型的对象一起使用,其参数至少应有 一 个是类对象(或类对象的引用)。

也就是说,参数不能全部是 C++的标准类型,以防止用户修改用于标准类型数据成 员的运算符的性质,

(8)用于类对象的运算符一般必须重载,但有两个例外,运算符”=“和运算 符”&“不 必用户重载。

复制运算符”=“可以用于每一个类对象,可以用它在同类对象之间相互赋值。因为系统已为每一个新声明的类重载了一个赋值运算符,它的作用是逐个复制类中的 数据成员地址运算符&也不必重载,它能返回类对象在内存中的起始地址。

(9)应当使重载运算符的功能类似于该运算符作用于标准类型数据时候时所实现的功能。

例如,我们会去重载”+“以实现对象的相加,而不会去重载”+“以实现对象相 减的功能,因为这样不符合我们对”+“原来的认知。

(10)运算符重载函数可以是类的成员函数,也可以是类的友元函数,还可以是既非类的成员函数也不是友元函数的普通函数

操作符重载

#if 1
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>using namespace std;class Complex
{
public:Complex(int a, int b){this->a = a;this->b = b;}void printComplex(){cout << "( " << this->a << ", " << this->b << "i )" << endl;}friend Complex complexAdd(Complex &c1, Complex &c2);/*friend Complex operator+(Complex &c1, Complex &c2);friend Complex operator-(Complex &c1, Complex &c2);*/Complex complexAdd(Complex &another){Complex temp(this->a + another.a, this->b + another.b);return temp;}//2操作符重载写在局部Complex operator+(Complex &another){Complex temp(this->a + another.a, this->b + another.b);return temp;}Complex operator-(Complex &another){Complex temp(this->a - another.a, this->b - another.b);return temp;}private:int a;//实数int b;//虚数
};Complex complexAdd(Complex &c1, Complex &c2) 
{Complex temp(c1.a + c2.a, c1.b + c2.b);   //要访问需要声明为友元函数return temp;
}
void test01() {Complex c1(1, 2);Complex c2(2, 4);c1.printComplex();c2.printComplex();Complex c3 = complexAdd(c1, c2);c3.printComplex();
}void test02() {Complex c1(1, 2);Complex c2(2, 4);c1.printComplex();c2.printComplex();Complex c3 = c1.complexAdd(c2);c3.printComplex();
}
//1操作符重载写在全局
#if 0
Complex operator+(Complex &c1, Complex &c2)  //+ 相当于函数名,接收两个参数//+ 左边是 第一个参数//+ 右边是 第二个参数  顺序固定
{Complex temp(c1.a + c2.a, c1.b + c2.b);return temp;
}Complex operator-(Complex &c1, Complex &c2)
{Complex temp(c1.a - c2.a, c1.b - c2.b);return temp;
}#endif
//全部操作符重载调用
void test03() {Complex c1(1, 2);Complex c2(2, 4);c1.printComplex();c2.printComplex();//Complex c3 = operator+(c1, c2);  //ok//等价于Complex c3 = c1 + c2;   //此种为隐式写法// c1 + c2  等价于    operator+(c1,c2)  全局的调用方式// c1 + c2  也等价于  c1.operator+(c2)  局部调用方式//所以局部调用方式和全局调用方式只能存在一个c3.printComplex();
}
void test04() {Complex c1(1, 2);Complex c2(2, 4);c1.printComplex();c2.printComplex();//Complex c3=c1.operator+(c2);//等价于Complex c3 = c1 + c2;c3.printComplex();Complex c4 = c1 - c2;c4.printComplex();Complex c5 = c1-c2-c1; //当 operator-函数 返回为元素时ok  //c1-c2返回为匿名对象 //再调用函数 还为匿名对象 拷贝构造给c5//当 operator-函数返回引用时 错误  //c1-c2返回为为temp的别名//再调用函数时 temp已经析构 c1-c2变为乱码 再调用函数仍然为乱码c5.printComplex();
}
int main(void)
{cout << "------test01-----------" << endl;test01();cout << "------test02-----------" << endl;test02();cout << "------test03-----------" << endl;test03();cout << "------test04-----------" << endl;test04();return 0;
}
#endif

双目运算符(有两个参数):

#if 1
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>using namespace std;class Complex
{
public:/*friend Complex& operator+=(Complex &c1, Complex &c2);friend Complex& operator-=(Complex &c1, Complex &c2);*/Complex(int a, int b){this->a = a;this->b = b;}void printComplex(){cout << "( " << this->a << ", " << this->b << "i )" << endl;}//2操作符重载写在局部Complex& operator+=(Complex &another){this->a += another.a;this->b += another.b;return *this;}Complex& operator-=(Complex &another){this->a -= another.a;this->b -= another.b;return *this;}private:int a;//实数int b;//虚数
};//1操作符重载写在全局
#if 0
Complex& operator+=(Complex &c1, Complex &c2)  //+ 相当于函数名,接收两个参数//+ 左边是 第一个参数//+ 右边是 第二个参数  顺序固定
{c1.a += c2.a;c1.b += c2.b;return c1;
}Complex& operator-=(Complex &c1, Complex &c2)
{c1.a -= c2.a;c1.b -= c2.b;return c1;
}#endif
void test01() {Complex c1(1, 2);Complex c2(2, 4);c1.printComplex();c2.printComplex();(c1 += c2)+=c2;  //(c1.operator+=(c2)).operator(c2)c1.printComplex();c2.printComplex();
}
/*
( 1, 2i )
( 2, 4i )
( 5, 10i )
( 2, 4i )
*/
//全部操作符重载调用int main(void)
{cout << "------test01-----------" << endl;test01();/*cout << "------test02-----------" << endl;test02();cout << "------test03-----------" << endl;test03();cout << "------test04-----------" << endl;test04();*/return 0;
}
#endif

单目运算符:

#if 1
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>using namespace std;class Complex
{
public:/*friend Complex& operator++(Complex &c1);friend Complex& operator--(Complex &c12);friend const Complex& operator++(Complex &c1, int);*/Complex(int a, int b){this->a = a;this->b = b;}void printComplex(){cout << "( " << this->a << ", " << this->b << "i )" << endl;}//2操作符重载写在局部Complex& operator++(){this->a ++;this->b ++;return *this;}Complex& operator--(){this->a --;this->b --;return *this;}const Complex& operator++(int) {  //亚元Complex temp(this->a, this->b);this->a++;this->b++;return *this;}private:int a;//实数int b;//虚数
};//1操作符重载写在全局
#if 0
//重载的前置加加
Complex& operator++(Complex &c1)  //+ 相当于函数名,接收两个参数//+ 左边是 第一个参数//+ 右边是 第二个参数  顺序固定
{c1.a ++;c1.b ++;return c1;
}Complex& operator--(Complex &c1)
{c1.a--;c1.b--;return c1;
}#endif
//重载的后置加加  不可以用多次 所以用const限制
#if 0
const Complex& operator++(Complex &c1, int) { Complex temp(c1.a, c1.b);c1.a++;c1.b++;return c1;
}
#endif
void test01() {Complex c1(1, 2);Complex c2(2, 4);c1.printComplex();c2.printComplex();++c1;c1.printComplex();/*++c1;c1.printComplex();*/}
/*
( 1, 2i )
( 2, 4i )
( 2, 3i )
( 3, 4i )
*/
void test02() {int a = 0;//a++++;  编译错误 后置加加不可多次Complex c1(1, 2);Complex c2(2, 4);c1.printComplex();c2.printComplex();c1++;  //后置加加返回值添加const 使得c1++++ 编译错误c1.printComplex();
}
/*
( 1, 2i )
( 2, 4i )
( 2, 3i )
*/
int main(void)
{cout << "------test01-----------" << endl;test01();cout << "------test02-----------" << endl;test02();/*cout << "------test03-----------" << endl;test03();cout << "------test04-----------" << endl;test04();*/return 0;
}
#endif

左移右移操作符:

#if 1
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>using namespace std;class Complex
{
public:friend ostream& operator<<(ostream &os, Complex &c);friend istream& operator>>(istream &is, Complex &c);Complex(int a, int b){this->a = a;this->b = b;}void printComplex(){cout << "( " << this->a << ", " << this->b << "i )" << endl;}
#if 0//左移操作符只能不能够写在成员函数里 只能写在全局函数中 否则调用顺序会变反 c1<<cout;ostream& operator<<(ostream &os) {  //c1.operator<<(cout)os << "(" << this->a << "," << this->b << "i)";return os;}
#endif//2操作符重载写在局部private:int a;//实数int b;//虚数
};//1操作符重载写在全局
#if 1
//重载的前置加加
ostream& operator<<(ostream &os, Complex &c) {os << "(" << c.a << "," << c.b << "i)";return os;
}
istream& operator>>(istream &is, Complex &c) {cout << "a:";is >> c.a;cout << "b:";is >> c.b;return is;
}
#endifvoid test01() {Complex c1(1, 2);Complex c2(2, 4);cout << c1 << endl;cin >> c2;c1.printComplex();c2.printComplex();//cout << c1; //operator<<(cout,c1) 全局ok 局部不ok//c1 << cout;  ok}
/**/int main(void)
{cout << "------test01-----------" << endl;test01();/*cout << "------test02-----------" << endl;test02();cout << "------test03-----------" << endl;test03();cout << "------test04-----------" << endl;test04();*/return 0;
}
#endif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/567880.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux照片备份软件,Linux、Unix上5个惊艳开源备份软件

Linux和类Unix系统上5个惊艳的开源备份软件&#xff1a;Bacula、Amanda、Backupninja、Backuppc和UrBackup&#xff0c;这些都是既可以使用在Linux上也可以使用在Unix上面&#xff0c;他们的优点就是性能稳定&#xff0c;使用灵活。一个好的备份计划是非常必要的&#xff0c;这…

linux 添加重定向域名,Linux系统中Nginx的安装并进行域名认证和重定向

Linux系统中Nginx的安装并进行域名认证和重定向本文主要介绍Linux系统中Nginx的安装并进行域名认证和重定向&#xff0c;希望通过本知识点的讲解对大家今后的学习和工作有所帮助&#xff0c;下面进行具体介绍&#xff1a;12.6 Nginx安装cd /usr/local/srcwget http://nginx.org…

linux有读EC RAM的工具吗,Step to UEFI (179)Shell下 EC Ram 读取工具

最近工作需要在 UEFI Shell 下Check EC Ram 的设定&#xff0c;发现手上只有 Windows 下的读取工具(RW Everything)。于是研究了一下如何在Shell 读取 EC Ram。根据【参考1】读取的流程如下&#xff1a;Port 66 CommandsThere are also some EC commands that use ports 0x66 …

C++基础13-类和对象之继承1

在 C中可重用性(software reusability)是通过继承(inheritance)这一机制来实现的。 如果没有掌握继承性,就没有掌握类与对象的精华。 总结&#xff1a; 1、只要是父类中的private成员&#xff0c;不管是什么继承方式&#xff0c;儿子都访问不了&#xff0c;但它是存在在儿子之…

C++基础13-类和对象之继承2

总结&#xff1a; 1、子类对象可以当做父类对象使用 2、子类对象可以直接赋值给父类对象 3、子类对象能够直接初始化父类对象 4、父类指针可以直接指向子类对象 5、凡是继承过来的属性和函数都可以在子类中用this-> 进行访问 6、默认构造函数并不会初始化数据成员 7、如果…

C++基础14-类和对象之多继承与虚继承

多继承&#xff1a;一个类有多个直接基类的继承关系称为多继承 总结&#xff1a; 1、一般将具有菱形样式继承方式的某些类声明为虚继承 3、虚继承的主要目的是为了防止二义性 2、虚继承就是在继承方式前加virtual 如果一个派生类从多个基类派生&#xff0c;而这些基类又有一…

linux系统安装ntp,CentOS下NTP安装配置

安装yum install ntp配置文件 /etc/ntp.confrestrict default kod nomodifynotrap nopeer noqueryrestrict -6 default kod nomodify notrap nopeer noqueryrestrict 127.0.0.1restrict -6 ::1# 用restrict控管权限# nomodify - 用户端不能更改ntp服务器的时间参数# noquery - …

C++基础15-类和对象之多态

总结&#xff1a; 1、在父类中申明虚函数时&#xff0c;一般情况下在子类中也申明&#xff08;便于读代码&#xff09; 一、赋值兼容 赋值兼容规则是指在需要基类对象的任何地方都可以使用公有派生类的对象来替代。 赋值兼容是一种默认行为,不需要任何的显示的转化步骤。 …

傲云浏览器linux,Centos7安装部署zabbix监控软件

目录部署监控服务器部署监控服务器Zabbix ServerWeb页面验证设置部署监控服务器一、安装LNMP环境Zabbix监控管理控制台需要通过Web页面展示出来&#xff0c;并且还需要使用MySQL来存储数据&#xff0c;因此需要先为Zabbix准备基础LNMP环境。1. wget下载官网Nginxwget http://ng…

c语言环境变量的作用,C语言获取系统环境变量

C语言获取系统环境变量可以通过如下代码实现.#include #include char *platform(){//获取系统变量信息char *ret;extern char **environ;char **env environ;//打印系统变量信息/*while(*env){//puts(*env);env;}*/ret getenv("OS"); //for windows_ntif(NULL ! re…

mysql索引创建及使用注意事项

总结&#xff1a; 1、在使用索引时&#xff0c;一般情况下不建议使用like操作。如果使用&#xff0c;则%放在后面。否则不会使用索引。like ‘%abd%’不会使用索引,而like ‘aaa%’可以使用索引.&#xff08;最左缀原则&#xff09; 2、单列索引的使用&#xff1a; 《1》 只…

mulitpartfile怎么接收不到值_和平精英信号接收区和信号值是什么?信号值怎么恢复...

[闽南网]和平精英公测开启&#xff0c;和平精英与刺激战场有什么不同呢&#xff1f;今天小编就为大家带来了信号值详解&#xff01;各位玩家千万不要错过呀&#xff01;信号值详解信号接收区和信号值是什么&#xff0c;对选手有什么影响&#xff1f;在游戏战斗界面中&#xff0…

制备pdms膜的方法_船体用钢板基底超疏水表面的制备和性能

鲨鱼皮具有神奇的微纳双层结构&#xff0c;其微米级肋条状结构在水中的整流效果可减小水的阻力。纳米级刺状突起或刚毛具有疏水特性&#xff0c;使植物抱子很难附着其上&#xff0c;海藻等植物也不能在其表面生长&#xff3b;1,2&#xff3d;。这种微纳结构及其疏水性的共同作用…

递归题型解析

#include<iostream> using namespace std; int foo(int n) {if (n < 1)return n;return (foo(n - 1) foo(n - 2)); } int main() {printf("%d\n", foo(5));return 0; } 解析&#xff1a; foo(5)foo(4)f00(3)foo(3)foo(2)foo(3)2foo(3)foo(2)2(foo(2)foo(1…

64位c语言调用32位glibc,glibc fclose源代码阅读及伪造_IO_FILE利用fclose实现任意地址执行...

简介最近学习了一下_IO_FILE的利用&#xff0c;刚好在pwnable.tw上碰到一道相关的题目。拿来做了一下&#xff0c;遇到了一些困难&#xff0c;不过顺利解决了&#xff0c;顺便读了一波相关源码&#xff0c;对_IO_FILE有了更深的理解。文章分为三部分&#xff0c;分别是利用原理…

戴尔笔记本电脑开机黑屏怎么办_戴尔笔记本电脑充不进电怎么办

笔记本电脑电池充不进电要怎么办呢&#xff1f;笔记本电脑之所以这么受欢迎&#xff0c;是因为笔记本有配备电池&#xff0c;能够在没有电源的情况下使用五六个小时。而电池的电用光后&#xff0c;就需要进行充电。不过有些用户反映说&#xff0c;自己的电池充不进电&#xff0…

IIS安装2个SSL_顶级域名0元撸-免费注册2个腾讯云域名 免费SSL证书

前言这两天折腾甜糖CDN&#xff0c;为了收益最大化申请了公网IP&#xff0c;于是顺带折腾了一下群晖外网访问。使用的DDNS方案是腾讯dnspod&#xff0c;注册一个便宜的顶级域名访问我的群晖&#xff0c;折腾过程中发现可以免费注册2个顶级域名&#xff0c;不敢独享发出来大家一…

三菱a系列motion软体_工控电缆如何制作?(以三菱PLC、触摸屏为例)

RS232接口的三菱Q系列PLC编程通讯电缆三菱GT11/GT15触摸屏RS232串口编程电缆三菱GT11/GT15触摸屏连接Q系列PLC电缆三菱GT11/GT15触摸屏连接FX2/FX2C/A/QnA系列PLC电缆三菱GT11/GT15 触摸屏连接FX3U/FX2N/FX1N系列PLC电缆FX2、A系列PLC到A970GOT人机介面连接电缆FX0s/FX0n/FX2n/…

电脑入门完全自学手册_「新书推荐」新能源汽车维修完全自学手册

《新能源汽车维修完全自学手册》作者&#xff1a;广州瑞佩尔信息科技有限公司 、胡欢贵售价&#xff1a;85.00上市时间&#xff1a;2020年7月本书内容分为 8 章, 第 1 章为高压安全系统, 主要介绍了新能源汽车中高压安全防护装置构造以及维修所需的安全防护工具、 安全作业规范…

C/C++混淆点-左移右移操作符

对一个数实行左移或者右移操作&#xff0c;即先把操作数转换为二进制&#xff0c;然后左移&#xff08;>>&#xff09;即从左到右开始舍弃&#xff0c;右移&#xff08;<<&#xff09;即从各位之后开始加0。最后再转换为十进制。 #include<iostream> using…