浅谈运算符重载与友元函数
发布日期:2022-02-07 06:39:45
浏览次数:2
分类:技术文章
本文共 3215 字,大约阅读时间需要 10 分钟。
Vector强化版
大纲:
1. 运算符重载 3. 友元函数 4. 思考一个问题
先把Vector类的代码放出来
相比上次的Vector省略了一些// Vector.h#ifndef VECTOR_H#define VECTOR_Hclass Vector{private: int x; int y;public: void show() const;};#endif
// Vector.cpp#include "Vector.h"#includevoid Vector::show() const{ using namespace std; cout << x << "," << y << endl; return ;}。。。。。。
如果要把一个矢量相加减
你是否梦想着可以用下面的代码来实现呢?//test.cpp#include "Vector.h"#includeusing namespace std;int main(){ Vector v1(2,3); Vector v2(3,4); Vector vp; Vector vm,vm2; vp = v1 + v2; vm = v1 * v2; vm2 = 3 * vm; cout << v; return 0;}
可是,Vector类对象并不是普通的内置类型
计算机并不知道如何将他们相加相乘 更不知道如何用cout将这个类输出 这个时候,全都需要我们自己定义运算符运算符重载
两个double类型的数据可以用运算符+相加
两个int类型的数据也可以用运算符+相加 诶,+号就像函数一样 可以根据不同的参数类型执行不同的操作 其实,运算符重载和函数重载是一样的呢 再其实,运算符其实就是个函数 下面先放出一个运算符重载的实例// 函数原型Vector operator+(Vector v1,Vector v2);// 函数定义Vector operator+(Vector v1,Vector v2){ Vector temp; temp.x = v1.x + v2.x; temp.y = v1.y + v2.y; return temp;}
在这个函数定义中,
+号在函数里用了operator+表示 注意:这里说明了,运算符是可以有两种表示方式的 一种是运算符表示法:v = v1 + v2;
y一种是函数表示法:v = operator+(v1,v2);
然后其他的东东和普通的函数时一样的 可是,这个函数是不能用的 还记得以前说到的,
非成员函数,是不能够访问类的私有成员的 要解决这个问题 1. 在类中定义运算符重载 2. 友元函数
类中运算符重载与普通运算符重载区别
还记得以前说到的
类成员函数,会隐式的传递this指针 下面还是先给一个类中定义运算符重载的例子Vector Vector::operator+(Vector v1){ Vector temp; temp.x = v1.x + x; temp.y = v1.y + y; return temp;}
区别:
1. 使用作用域解析运算符 2. 少传递了一个参数,原本需要两个操作数的+ 只传递了一个对象?在类中,会隐式的传递自身作为运算符的一个操作数
如:v = v1 + v2 用函数表示法可表示为 v = v1.operator+(v2);
友元函数
对上面的问题,还有一种解决方案
虽然非成员函数无法访问类的私有成员 但我可以通过一种特殊的方式 让非成员函数获得访问私有成员的特权 友元函数!!友元函数的语法要求有两个:
1. 函数的原型前面加上friend关键字 2. 函数原型必须放在类定义内部下面给例子
// 函数原型class Vector{ ...public: ... friend Vector operator+(Vector v1,Vector v2);}// 函数定义Vector operator+(Vector v1,Vector v2){ Vector temp; temp.x = v1.x + v2.x; temp.y = v1.y + v2.y; return temp;}
函数的调用方式略有不同
v = v1 + v2;
实际上是这样的函数调用v = operator+(v1, v2);
其他操作的实现
乘法和加法类似
也有友元版运算符重载 和类内运算符重载两种形式 不过有一个需要思考的vm2 = 3 * v2
这个该怎么办呢? 在类内运算符重载中
二元运算符的第一个操作数是调用对象本身 第二个操作数是函数参数 如:v = v1 + v2
用函数表示法可表示为v = v1.operator+(v2);
对vm2 = 3 * v2
// 函数原型class Vector{ ...public: ... friend Vector operator*(int d ,Vector v);}// 函数定义Vector operator*(int d ,Vector v){ Vector temp; temp.x = v.x * d; temp.y = v.y * d; return temp;}
思考
上面的运算符重载能否实现以下操作
v = v1 + v2 + v3 + v4;
运算符重载,是否能够重载任意运算符?
重载能否改变现有的运算规则
(比如把两个int类的+法自定义)如何实现<< 的运算符重载从而实现
cout << v;
1.
可以
假设这里用的是类内的运算符重载 根据+号从左往右结合 先算v1 + v2v = v1.operator(v2) + v3 + v4;
然后根据函数定义 该函数返回一个Vector对象 也就是说 v1.operator(v2)
本身就是一个Vector 对象 然后这个对象与v3结合,再使用+号 v = v1.operator(v2).operator+(v3) + v4;
后面以此类推 关键是在该运算符函数返回对象(当然也可以返回对象的引用) 2.
还是有很多限制的
比如: 1. 运算符操作数至少一个数是用户自定义的类型 2. 不违反现有的句法规则 3. 不创造新的运算符 4. 一部分运算符不可以重载 一部分运算符只能在类内作为类成员函数重载 一部分运算符类内类外均可具体的可以自行了解
当然加减乘除都是类内类外均可的3
哎呀……上面不小心回答完了
4
先放例子
// 函数原型class Vector{ ...public: ... friend ostream & operator<<(ostream & os, const Vector & temp );}// 函数定义ostream & operator<<(ostream & os, const Vector & temp ){ os << temp.x << "," << temp.y << endl ; return os;}
详细解释看 c++ primer plus p392 - 394吧
不大好解释呢 反正……cin是一个ostream类的对象 所以要想cin << v;
函数的形参列表就必须与上面对应 (见函数定义) 一些比较好的博客
转载地址:https://blog.csdn.net/wyfwyf12321/article/details/54745772 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
感谢大佬
[***.8.128.20]2024年04月13日 12时25分08秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
python - 使用sql 分析(06 - 15)国内各省GDP
2019-04-27
python - 抓取汇率数据分析美元和欧元对RMB的变化曲线
2019-04-27
python 数据科学 - 【回归分析】 ☞ 线性回归(1)
2019-04-27
python 数据科学 - 【回归分析】 ☞ 线性回归(2)
2019-04-27
python - 批量更改文件名(过滤掉某个字符串)
2019-04-27
python 数据科学 - 【分类模型】 ☞ 决策树
2019-04-27
python - zip、numpy.c 函数
2019-04-27
python 数据科学 - 【分类模型】 ☞ 逻辑回归
2019-04-27
python 数据科学 - 【分类模型】 ☞ 稳健滴 SVM 支持向量机
2019-04-27
python - selenium 处理 alert
2019-04-27
Java - Set、List、Map
2019-04-27
Java - OnlyLady Spider(HttpClient 4.5 )
2019-04-27
Math - 高斯分布(正态分布)
2019-04-27
android学习笔记----简易音乐播放器原理
2019-04-27
Unity编辑器扩展——标签属性Attribute
2019-04-27
Unity中实现拖拽操作
2019-04-27
Unity中的UGUI事件系统
2019-04-27
C#中的常量
2019-04-27
C#中的静态变量与非静态变量
2019-04-27