C++运算符重载学习

关键点摘要:

1、=、()、[]、->重载为成员函数P493,其余运算符的参数换序具有相同结果的最好定义成友元,因为string + "append"相当于string.+("append"),换序之后"append".+(string)就不行了。

2、临时对象比较特殊,会默认为const的,因为改变它没有什么意义。下面例子会说明遇到的一个问题。

目标:

先实现一个complex类,即复数的定义,包括+、-、*、/运算的重载。

 

一、类定义如下:默认构造、拷贝构造、拷贝赋值、析构.....balabala

 1 //
 2 // Created by forthee on 2022/1/16.
 3 //
 4 
 5 #ifndef HELLO_WORLD_CHAPTER14_H
 6 #define HELLO_WORLD_CHAPTER14_H
 7 
 8 #endif //HELLO_WORLD_CHAPTER14_H
 9 
10 #include <iostream>
11 using namespace std;
12 
13 class complex {
14 private:
15     float imag;
16     float real;
17 
18 public:
19     //
20     virtual ~complex() = default;
21     complex():real(0.0), imag(0.0){};
22     complex(float real, float imag) : real(real), imag(imag){};
23     complex(complex &in):real(in.real), imag(in.imag){};
24     complex& operator=(const complex &in) = default;
25     // operator
26     complex operator+(complex &b);
27     complex operator-(complex &b);
28     complex operator*(complex &b);
29     complex operator/(complex &b);
30 
31     //friend
32     friend ostream& operator<<(ostream &out, complex &PrintInfo);
33 
34 };
35 
36 void ComplexCalc(complex a, complex b);
37 
38 #include <iostream>
39 #include "Chapter14.h"
40 
41 using namespace std;
42 
43 ostream& operator<<(ostream &out, complex &PrintInfo) {
44     if (PrintInfo.imag >= 0) {
45         out<<PrintInfo.real<<"+"<<PrintInfo.imag<<"j";
46     } else {
47         out<<PrintInfo.real<<PrintInfo.imag<<"j";
48     }
49     return out;
50 }
51 
52 complex complex::operator+(complex &b) {
53     return complex(real+b.real, imag+b.imag);
54 }
55 
56 complex complex::operator-(complex &b) {
57     return complex(real-b.real, imag-b.imag);
58 }
59 
60 complex complex::operator*(complex &b) {
61     return complex(real*b.real - imag*b.imag, real*b.imag + imag*b.real);
62 }
63 
64 complex complex::operator/(complex &b) {
65     if ((b.real == 0) && (b.imag == 0)) {
66         cout<<"Illegal denominator to devide !"<<endl;
67         return complex(0,0);
68     }
69 
70     complex temp;
71     temp.imag = (b.real*imag - real*b.imag)/(b.real*b.real + b.imag*b.imag);
72     temp.real = (real + temp.imag*b.imag)/b.real;
73     return temp;
74 }
错误示例

void ComplexCalc(complex a, complex b) {
  cout<<complex(5,5)<<endl; //此处报错
}

 万万没想到,为什么呢?看到error: cannot bind non-const lvalue reference of type 'complex&' to an rvalue of type 'complex',猜想是不是得定义成const的?百度一下,果然,临时对象是const类型的,改变它也没有意义,所以friend ostream& operator<<(ostream &out, complex &PrintInfo);改为 friend ostream& operator<<(ostream &out, const complex &PrintInfo);解决问题!

 

 1 #include <iostream>
 2 #include "Chapter14.h"
 3 
 4 using namespace std;
 5 
 6 ostream& operator<<(ostream &out, const complex &PrintInfo) {
 7     if (PrintInfo.imag >= 0) {
 8         out<<PrintInfo.real<<"+"<<PrintInfo.imag<<"j";
 9     } else {
10         out<<PrintInfo.real<<PrintInfo.imag<<"j";
11     }
12     return out;
13 }
14 
15 complex complex::operator+(complex &b) {
16     return complex(real+b.real, imag+b.imag);
17 }
18 
19 complex complex::operator-(complex &b) {
20     return complex(real-b.real, imag-b.imag);
21 }
22 
23 complex complex::operator*(complex &b) {
24     return complex(real*b.real - imag*b.imag, real*b.imag + imag*b.real);
25 }
26 
27 complex complex::operator/(complex &b) {
28     if ((b.real == 0) && (b.imag == 0)) {
29         cout<<"Illegal denominator to devide !"<<endl;
30         return complex(0,0);
31     }
32 
33     complex temp;
34     temp.imag = (b.real*imag - real*b.imag)/(b.real*b.real + b.imag*b.imag);
35     temp.real = (real + temp.imag*b.imag)/b.real;
36     return temp;
37 }
38 
39 void ComplexCalc(complex a, complex b) {
40     cout<<"("<<a<<") + ("<<b<<") = "<<a+b<<endl;
41     cout<<"("<<a<<") - ("<<b<<") = "<<a-b<<endl;
42     cout<<"("<<a<<") * ("<<b<<") = "<<a*b<<endl;
43     cout<<"("<<a<<") / ("<<b<<") = "<<a/b<<endl;
44 }
complex类

TODO:重载返回的都是对象而不是引用,效率其实比较低,待改写! 

 








posted @ 2022-01-16 22:40  loveforthee  阅读(54)  评论(0)    收藏  举报