值得思考的问题:
示例:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 int main() 7 { 8 int i = 0; 9 10 i++; 11 12 ++i; 13 14 return 0; 15 }
反汇编如下:
我们看到i++和++i对应的汇编是完全一样的。仅仅是寄存器不一样。
因为我们并没有使用这两行语句的返回值,而是单纯的两行i++和++i,所以编译器优化后,将返回值抛弃,因此它们的底层汇编是一样的。
linux下g++编译器的反汇编如下:
可以得到结论,独立的两行i++和++i是没有差别的。
意想不到的事实:
思考:
++操作符重载:
示例程序:
将++t的返回值来初始化tt,打印tt的值为1,这是正确的。
添加后置++:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class Test 7 { 8 int mValue; 9 public: 10 Test(int i) 11 { 12 mValue = i; 13 } 14 15 int value() 16 { 17 return mValue; 18 } 19 20 Test& operator ++ () 21 { 22 ++mValue; 23 24 return *this; 25 } 26 27 Test operator ++ (int) 28 { 29 Test ret(mValue); 30 31 mValue++; 32 33 return ret; 34 } 35 }; 36 37 int main() 38 { 39 Test t(0); 40 41 t++; 42 43 ++t; 44 45 return 0; 46 }
前置++过后应该返回对象本身(引用),正如第20行所示,这也是前置++的原生语义:先将当前的操作数加1,然后返回当前的操作数。
后置++操作符的原生语义是先将自身的值(非引用)返回,然后加1。第27行实现的正是这样的语义,通过一个临时对象来返回自身原来的值。
后置++先将当前对象的值保存下来,只能保存到一个临时对象,因此返回时也只能返回值不能返回引用。
前置++和后置++参数有差异,返回值也有差异。
这里重载的前置++和后置++,在我们单独调用t++和++t时是有区别的,因为它们本质上是调用的函数,这一点不同于我们上面反汇编的++i和i++。
后置的++会调用到构造函数和析构函数。
因此,在回答i++和++i有没有区别时,我们要注意了,要看i是基本类型,还是我们的自定义类型。
真正的区别:
复数类的进一步完善:
1 #ifndef _COMPLEX_H_ 2 #define _COMPLEX_H_ 3 4 class Complex 5 { 6 double a; 7 double b; 8 public: 9 Complex(double a = 0, double b = 0); 10 double getA(); 11 double getB(); 12 double getModulus(); 13 14 Complex operator + (const Complex& c); 15 Complex operator - (const Complex& c); 16 Complex operator * (const Complex& c); 17 Complex operator / (const Complex& c); 18 19 bool operator == (const Complex& c); 20 bool operator != (const Complex& c); 21 22 Complex& operator = (const Complex& c); 23 24 Complex& operator ++ (); 25 Complex operator ++ (int); 26 }; 27 28 #endif
1 #include "Complex.h" 2 #include "math.h" 3 4 Complex::Complex(double a, double b) 5 { 6 this->a = a; 7 this->b = b; 8 } 9 10 double Complex::getA() 11 { 12 return a; 13 } 14 15 double Complex::getB() 16 { 17 return b; 18 } 19 20 double Complex::getModulus() 21 { 22 return sqrt(a * a + b * b); 23 } 24 25 Complex Complex::operator + (const Complex& c) 26 { 27 double na = a + c.a; 28 double nb = b + c.b; 29 Complex ret(na, nb); 30 31 return ret; 32 } 33 34 Complex Complex::operator - (const Complex& c) 35 { 36 double na = a - c.a; 37 double nb = b - c.b; 38 Complex ret(na, nb); 39 40 return ret; 41 } 42 43 Complex Complex::operator * (const Complex& c) 44 { 45 double na = a * c.a - b * c.b; 46 double nb = a * c.b + b * c.a; 47 Complex ret(na, nb); 48 49 return ret; 50 } 51 52 Complex Complex::operator / (const Complex& c) 53 { 54 double cm = c.a * c.a + c.b * c.b; 55 double na = (a * c.a + b * c.b) / cm; 56 double nb = (b * c.a - a * c.b) / cm; 57 Complex ret(na, nb); 58 59 return ret; 60 } 61 62 bool Complex::operator == (const Complex& c) 63 { 64 return (a == c.a) && (b == c.b); 65 } 66 67 bool Complex::operator != (const Complex& c) 68 { 69 return !(*this == c); 70 } 71 72 Complex& Complex::operator = (const Complex& c) 73 { 74 if( this != &c ) 75 { 76 a = c.a; 77 b = c.b; 78 } 79 80 return *this; 81 } 82 83 Complex& Complex::operator ++ () 84 { 85 a = a + 1; 86 b = b + 1; 87 88 return *this; 89 } 90 91 Complex Complex::operator ++ (int) 92 { 93 Complex ret(a, b); 94 95 a = a + 1; 96 b = b + 1; 97 98 return ret; 99 }
小结: