C++运算符重载引用传参与返回引用的小小心得
1 #include <bits/stdc++.h>
2
3 using namespace std;
4
5 //平面向量类,提供完成向量运算和比较的API
6 //除递增运算符和左移运算符重载外其他函数省略
7
8 class Vec2D
9 {
10 //形参cout和函数返回值使用引用是为了保证拷贝构造函数的调用,以确保全局cout对象唯一
11 //形参vec使用引用是为了提高函数调用效率,也可以不用
12 friend ostream& operator<<(ostream& cout, Vec2D& v); //重载<<运算符
13
14 public:
15 Vec2D(double x, double y); //有参构造函数
16 Vec2D& operator++(); //重载前置++运算符
17 Vec2D operator++(int); //重载后置++运算符
18
19 private:
20 double _x;
21 double _y;
22
23 };
24
25 ostream& operator<<(ostream& cout, Vec2D& v)
26 {
27 cout << '(' << v._x << ',' << v._y << ')' << endl;
28 return cout;
29 }
30
31 Vec2D::Vec2D(double x, double y)
32 {
33 _x = x;
34 _y = y;
35 }
36
37 Vec2D& Vec2D::operator++()
38 {
39 this->_x++;
40 this->_y++;
41 return *this;
42 }
43
44 Vec2D Vec2D::operator++(int)
45 {
46 Vec2D pre = *this;
47 this->_x++;
48 this->_y++;
49 return pre;
50 }
51
52 void test01()
53 {
54 Vec2D v1{ 1, 1 };
55 cout << ++v1 << endl;
56 //cout << v1++ << endl;
57 }
58
59 int main()
60 {
61 test01();
62 return 0;
63 }
我在初学时遇到的一个问题是:重载后置++运算符时,应不应当返回对象的引用?
首先须明确,若令pre = *this,返回引用一定是错误的,因为这是一个开辟在栈内的局部对象,生命周期在成员函数内部,函数结束内存就被释放了;而引用本质是利用指针常量操作对象,利用指针操作不存在的内存是危险的。
其次,若想返回引用,须使用pre = new Vec2D(this->_x, this->_y),这是开辟在堆内的,因此可以安全返回其地址。但与之而来的问题是后续无法对其delete,容易造成内存泄漏。
因此,直接返回对象本身最为妥当,尽管会因此隐式调用一次拷贝构造函数。
与之而来的是第二个问题:代码中注释掉的一行cout << v1++ << endl,会报错:“没有与这些操作数匹配的‘<<’运算符”。
这是因为在定义<<重载时为了提高函数调用运行效率传递对象时,采取了传址调用(引用),而既然需要解引用,就要求实参必须是可以解引用的值,即左值;
而后置++运算符重载返回了一个局部对象,这是一个右值,不能作为左值,所以会报错;
修改方法有二:
(1)把<<运算符重载的形参v修改为传值调用,这样既可以传入一个右值了;
(2)在形参前加上const修饰,即:
friend ostream& operator<<(ostream& cout, const Vec2D& v);
这是因为当const 修饰一个左值引用(型如const Type &)时,表示该左值引用既可以引用一个左值,也可以引用一个右值(字面值或临时对象),而不带 const修饰的左值引用(型如Type &)只能引用一个左值,不能引用一个右值。
C++运算符重载引用传参与返回引用的小小心得的更多相关文章
- 引用传参与reference_wrapper
本文是<functional>系列的第3篇. 引用传参 我有一个函数: void modify(int& i) { ++i; } 因为参数类型是int&,所以函数能够修改传 ...
- ES6中generator传参与返回值
先看两个例子, 1, function* f() { for(var i=0; true; i++) { var reset = yield i; if(reset) { i = -1; } } } ...
- main函数的传参与返回
1.谁给main函数传参(1)调用main函数所在的程序的它的父进程给main函数传参,并且接收main的返回值.2.为什么需要给main函数传参(1)首先,main函数不传参是可以的,也就是说父进程 ...
- C++ 重载运算符返回值 和 返回引用的原因
原因是: +,-,*等返回不了引用,比如+运算符,可以如下重载(为了简单,假设A 只有int x:int y) A operator+(A a,A b) {A sum; sum.x=a.x+b.x ...
- 《挑战30天C++入门极限》C++运算符重载函数基础及其值返回状态
C++运算符重载函数基础及其值返回状态 运算符重载是C++的重要组成部分,它可以让程序更加的简单易懂,简单的运算符使用可以使复杂函数的理解更直观. 对于普通对象来说我们很自然的会频繁使用算数运 ...
- C++二级指针和指针引用传参
前提 一级指针和引用 已经清晰一级指针和引用. 可参考:指针和引用与及指针常量和常量指针 或查阅其他资料. 一级指针和二级指针 个人觉得文字描述比较难读懂,直接看代码运行结果分析好些,如果想看文字分析 ...
- C++基本之 运算符重载
=====>友元运算符#include <iostream> using namespace std; class Test { public: Test(int a = 0) { ...
- C++初阶(运算符重载汇总+实例)
运算重载符 概念: 运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似. 函数原型: 返回值 operator操作符(参数列表) 注意: ...
- C++程序设计方法3:数组下标运算符重载
数组下标运算符重载 函数声明形式 返回类型operator[](参数): 如果返回类型是引用,则数组运算符调用可以出现在等式的左边,接受赋值,即: Obj[index] = value; 如果返回类型 ...
- 《挑战30天C++入门极限》对C++递增(增量)运算符重载的思考
对C++递增(增量)运算符重载的思考 在前面的章节中我们已经接触过递增运算符的重载,那时候我们并没有区分前递增与后递增的差别,在通常情况下我们是分别不出++a与a++的差别的,但的确他们直接是 ...
随机推荐
- absible笔记第一章 (ansibles基础与playbook常用模块)
一. ansibles基础与playbook 1.优先级问题 ANSIBLE_CONFIG ansible.cfg 项目目录 ...
- -behaviour()的使用,他具体有什么作用
Eralng 编程中的OTP OTP里面创建进程时 常用有四大behaviour • supervisor • gen_server • gen_fsm • gen_event 在erlang的编译器 ...
- yolo v7使用triton部署
https://github.com/WongKinYiu/yolov7/tree/main/deploy/triton-inference-server
- 如何在winform打包时带上sqlite数据库
sqlite数据库下载及使用:https://blog.csdn.net/Yyuanyuxin/article/details/105508886sqlite数据库可视化工具-- DB.Browser ...
- sql offset 优化
// let groupSql = ` select id,jd_gcj02ll, wd_gcj02ll from ${tablename_qiye} where id between ${size ...
- 浅谈JS输出中的“+”作用问题
背景(问题) web前端考试有这么一道题目(为了阅读方便和应文章的景,小编将题目进行了微调) <input type="number" value="1" ...
- es启动和停止命令
1.启动命令 使用elasticsearch用户来启动,进入bin目录(例:home/db_app/elasticsearch/elasticsearch-6.5.4/elasticsearch-cl ...
- centos6根分区扩容,非lvm
1.关闭虚拟机,删除里面的快照,将磁盘扩容 2.根分区为sda3,开机后输入fdisk /dev/sda,d,3删除sda3,然后n,p,3,w创建sda3,扇区的开始位置要一致 3.growpart ...
- 关于 echarts 使用 geo 制作地图 tooltip 不显示问题(转)
原文地址 我之前遇到过这问题,单独设置 tooltip 没效果,geo 下面也有 tooltip 属性,但是也不管用,网上查了一下说 geo 不支持 tooltip 提示框显示,就自己根据 echar ...
- CF908G 题解
题意 传送门 给 \(x\le10^{700}\),问 \(1\) 到 \(x\) 中每个数在各数位排序后得到的数的和.答案模 \(10^9+7\). 题解 学到一种新鲜的转化方式,来记一下. 将 \ ...