关于传值传引用,const的使用
发布日期:2022-02-07 06:39:45
浏览次数:2
分类:技术文章
本文共 3066 字,大约阅读时间需要 10 分钟。
实现Vector 类(四)
这里主要做一些优化
传入参数属性的选择
拿其中的一个函数作为例子
// 函数原型class Vector{ ...public: ... Vector operator+(Vector v1);}// 函数定义Vector Vector::operator+(Vector v1){ Vector temp; temp.x = v1.x + x; temp.y = v1.y + y; return temp;}
在这里,我们传入了一个v1对象
当我这样子调用Vector v1(2,3);Vector v2(3,4);Vector v;v = v1 + v2;
相当于这样子
v = v1.operator+(v2);
v2作为参数传进函数中 聪明的你们当然知道这是传值引用 所以,v2传入函数时会创建一个临时对象 然后用这个临时对象参与运算 最后返回一个另一个临时对象temp 退出函数时,v2形成的临时对象执行析构函数被销毁 临时对象temp赋值给对象v后被自动销毁 选择:
按值传递,按址传递,按引用传递 按值传递需要创建临时对象 需要消耗额外的计算与存储资源 最好是传入指针或引用 当然在C++中引用是更好的选择
因此我们可以这样修改
// 函数原型class Vector{ ...public: ... Vector operator+(Vector & v1);}// 函数定义Vector Vector::operator+(Vector & v1){ Vector temp; temp.x = v1.x + x; temp.y = v1.y + y; return temp;}
传入参数属性的选择(二)
按值传递和按引用传递(暂时不讨论指针了)
按值传递的最大优点是不会修改原来的数据 现在我们传入了引用 如果操作有失误,可能会使得源数据被修改 这时候我们可以考录传入const的引用 因此我们可以这样修改// 函数原型class Vector{ ...public: ... Vector operator+(const Vector & v1);}// 函数定义Vector Vector::operator+(const Vector & v1){ Vector temp; temp.x = v1.x + x; temp.y = v1.y + y; return temp;}
这样子传递参数,就能够防止源数据被修改
(当然如果本来就要修改的话那就不要const罗)关于构造函数的使用技巧
我们回顾下Vector我们定义的构造函数的原型
Vector(int a, int b);
事实上 构造函数不仅仅在初始化的时候可以调用 它本来就可以当成一个函数直接在类里使用 所以 上面的例子可以进一步优化 // 函数原型class Vector{ ...public: ... Vector operator+(const Vector & v1);}// 函数定义Vector Vector::operator+(const Vector & v1){ return Vector(v1.x + x, v1.y + y);}
这里构造函数Vector直接根据参数生成一个临时对象
然后把这个临时对象返回。 这样子能够使整个函数更为简洁 可读性也更强关于const的使用
刚刚讲到一个传入参数用const
还有一个作用 而且是一个很重要很重要的作用 我们可以像创建常量一样创建常量对象Vector v1(2,3);const Vector v2(3,4);
这样子,const的使用使v2成为常量对象
那可以这样子吗?Vector v1(2,3);const Vector v2(3,4);Vector v;v = v1 + v2;
这样子的调用
v = v1.operator+(v2); 参照 如果这样Vector operator+(Vector & v1);
v2是个常量,但是函数参数却不是常量引用
如果成功传递,将会导致原本是常量的内容被修改! 因此这样的参数传递是不能过的按值传递
由于改变的是临时变量 是不是const都没关系 按引用传递 由于会改变源数据 普通引用的参数只能传入普通的变量 const&的参数 既能接受普通变量又能接受const变量 兼容性++
关于const的使用(二)
Vector v1(2,3);const Vector v2(3,4);Vector v;
这样的声明
我能否这样做v = v2 + v1;
和刚刚的例子比起来,好像只是换了下顺序 但是他的函数调用形式变了 v = v2.operator+(v1);
好像也没什么问题?
注意!这里的v2是常量对象复习以前说过的this指针
this指针在对象中指的是 调用对象本身的指针 复习const成员函数 在成员函数后面加const 相当于给this指针加上了const 防止对象成员函数修改自身数据
复习完,再看看const对象
const对象 不就是自身数据不会被修改的对象吗 它的数据只要初始化之后 就不能够被修改 因此const对象里的this指针 应该全都要是const * 类型的 可是这里的运算符重载函数并不是const成员函数 里面的this指针不是const的 所以上面的调用v = v2.operator+(v1);
是行不通的 因此,只要是不需要修改自身数据
常量对象可能执行的类方法 都需要用const成员函数 修改方案如下:// 函数原型class Vector{ ...public: ... Vector operator+(const Vector & v1) const;}// 函数定义Vector Vector::operator+(const Vector & v1) const{ return Vector(v1.x + x, v1.y + y);}
如果对用一个函数有两个不同的版本
一个是const成员函数 一个不是const成员函数 那么常量对象调用函数将会执行const成员函数 普通对象将会调用const成员函数 这也个根据this指针const属性不同 导致函数形参列表不同特征标不同 然后函数重载的一个实例
总结
- 参数属性的选择,
- 按值传递,按引用传递
- 是否使用const
- 尽可能地使用const,能增强类的兼容性(对常量对象的兼容)
- const成员函数的理解(this指针的const属性)
- 构造函数的使用,能够大大降低程序的复杂度
至此,一个简单的Vector类
算是出来了
我们已经详细讲解了+号的重载 以及它的优化 之后我们就可以加上+
*
来用最舒服的方式 实现矢量之间最基本的运算 通过重载 >, >= , < , <= ,== 可以实现矢量之间的大小比较 还可以重载 +=, -=,*= 使得矢量的使用更加的接近普通变量 当然,还可以根据矢量的特征 自己在定义多几个矢量的类成员函数 比如计算两个矢量之间的角度 还可以在矢量类私有成员中加上长度 并在初始化时自动计算长度 从而在类内部调用长度的时候更为方便转载地址:https://blog.csdn.net/wyfwyf12321/article/details/54766934 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
第一次来,支持一个
[***.219.124.196]2024年04月11日 20时59分16秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
ArcServer 无法正常启动,卸载IE7.0!
2021-06-29
为我加油吧-CTO 冲!
2021-06-29
【Linux】Linux中at命令详解
2021-06-29
[【Android】Android之ContentProvider总结
2021-06-29
【Android】Android中ContentProvider组件详解
2021-06-29
【Android】ContentProvider和Uri详解
2021-06-29
【Android】Android Service的生命周期
2021-06-29
【Android】 Android Service生命周期及用法
2021-06-29
【Linux】Linux crontab 命令详解
2021-06-29
【Android】Android Service 服务
2021-06-29
【Android】GitHub Android 开源项目汇总
2021-06-29
【Android】Android模拟器无法上网问题
2021-06-29
【Linux】Linux中正则表达式
2021-06-29
【Linux】Linux中目录结构说明
2021-06-29
【Linux】Linux中Vim基础
2021-06-29
【Android平台】 Alljoyn学习笔记二 编译自带的demo的步骤
2021-06-29
【Android平台】 Alljoyn学习笔记四 Android Core API参考
2021-06-29
【Alljoyn】Alljoyn学习笔记五 AllJoyn开源技术基础概念解析
2021-06-29
【Alljoyn】 Alljoyn学习笔记六 Alljoyn基本概念
2021-06-29