首页 > 编程语言 >C++运算符重载引用传参与返回引用的小小心得

C++运算符重载引用传参与返回引用的小小心得

时间:2023-01-31 09:57:05浏览次数:45  
标签:返回 ++ 左值 C++ 运算符 Vec2D 引用

 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++,运算符,Vec2D,引用
From: https://www.cnblogs.com/code-gilgamesh/p/17077949.html

相关文章

  • 字符串连接与三元运算符
    字符串连接(+,String)字符串连接符:从字符串后面开始连接,全部变为字符串;""+a+b:直接字符串连接,因为字符串放在前面;a+b+"":先算a+b,然后再字符串连接,因为字符串放在在后面; ......
  • 逻辑、位运算符
    逻辑运算符&&(与):逻辑与运算,两个变量都为真,结果才为true;||(或):逻辑或运算,两个变量有一个为真,则结果才为true;!(非):如果是真,则变为假,如果是假则变为真;  位运算符&(......
  • 小熊猫C++编写海龟作图程序
    未完待续。。。初遇问题使用内置的模板创建海龟作图小程序:但是,编译运行时出现错误:rturtle海龟绘图命令小结在小海龟行动之前,我们需要熟悉一下绘图环境。这里用列表小结一下......
  • JVM是如何解决跨代引用问题的?
    本文已收录至Github,推荐阅读......
  • C++ 编译相关
    目录一、cmake前言安装步骤二、cmake与make两者区别为什么不直接使用项目编译链接工具(gcc/g++...)为什么不直接使用make或者Ninjacmake指定编译器(cmake-G)三、CMakeLists......
  • C++ STL stack
    #include<stack>头文件usingnamespacestd;作用这个很清楚了,FILO运用在:括号匹配、波兰式计算问题上(未完待续)创建一个参数,默认使用deque容器stack<typenameT,t......
  • 下标引用函数调用和表达式求值
    前言:下标的用法非常非常的重要关乎到数组函数指针结构体等等一切,函数的调用也有很多细节表达式求值涉及优先级问题要注意1.下标引用、函数调用和结构成员注:一切下标又是从0......
  • C/C++学生成绩信息管理[2023-01-30]
    C/C++学生成绩信息管理[2023-01-30]2.学生成绩信息管理【问题描述】利用哈希表完成学生成绩信息的管理。每个学生记录包含学生学号(Number)、真实姓名(Name)、网名(Scre......
  • C++ 模板之类模板
    使用类模板,可以事先不确定成员变量的类型,假如我们要写一个先进后出的栈,这个栈既可以放入int,也可以放入long,还可以放入string,那么就需要使用模板技术,否则,类的成员变量将难以......
  • C++ 运算符重载
    技术,是实现目标的手段,重载运算符,可以让程序看起来更优美,更优美的程序更具有可读性,如果不重载,使用函数一样可以达到目的,但那样子程序看起来很蹩脚,直接上代码    #inclu......