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 &)只能引用一个左值,不能引用一个右值。

最新文章

  1. Atitit.可视化与报表原理与概论
  2. jquery1.7.2的源码分析(四)$.Deferred(2)
  3. GO语言练习:为类型添加方法
  4. WPF TextBlock文本纵向排列
  5. redis数据库使用测试
  6. [改善Java代码]避开基本类型数组转换列表陷阱
  7. javascript BOM对象 第15节
  8. JQuery EasyUI 对话框的使用方法
  9. Socket 理解
  10. ps入门教程:画笔工具、铅笔工具、渐变工具等的使用
  11. 各个浏览器开启CSS Grid Layout的方式
  12. (四十四)TabBarController和NagivationController配合
  13. C#单元测试,带你快速入门
  14. Day 23 面向对象(二)
  15. 【java8】使用lambda表达式对List去重
  16. Hadoop-HDFS
  17. js day01
  18. week07 13.1 NewsPipeline之 一 NewsMonitor
  19. Vue项目页面跳转时候的,浏览器窗口上方的进度条显示
  20. 怎样用SQL语句查看查询的性能指标

热门文章

  1. The Nine Arches Bridge
  2. ARMv7-Protected Memory System Architecture(PMSA)
  3. Win10下VM虚拟机桥接模式无法上网的相关问题?
  4. 常用的Shell实用脚本
  5. koa源代码解析
  6. DevExpress 动态换肤
  7. 关于 echarts 使用 geo 制作地图 tooltip 不显示问题(转)
  8. 看K线学炒股(8.5)
  9. HTML5代码大全
  10. 【剑指Offer】【链表】合并两个排序的链表