0%

自己封装自定义类型

2020年5月16日 下午10:47

总结:

  1. 这个过程最大的收获是:设计函数接口时,灵活的使用const,&引用。
    1. 这里面的技巧是:自己要理解这个函数的”语义“,这个”语义“里其实就回答了:这部分与语言无关,用人类正常的生活思维反而更加容易理解
      1. 是否需要构造新的临时变量
        1. 返回参数是否使用&
      2. 是否会对传入的参数值进行改变
        1. 涉及到对参数的const
        2. 对成员函数的const
        3. 对临时对象的const 引用
    2. operator= ,operator+=,operator++() 这三个都是可以直接对传入的进行操作,所以没必要这三个重载有两个要求:
      1. 函数不能声明为const
      2. 返回值要声明为&
  2. 我纠结过的一个点:Complex operator+(const Complex &c) const;
    1. 这个+的重载,从语义的角度来说,的确需要返回一个临时变量
    2. 但是,我在想能不能尝试使用Complex& 作为返回值?
    3. 答案是不行:
      1. 首先,从语义上分析是必须有一个临时变量的!所以这就从理论上保证了其实是不可能做到没临时变量的。
      2. 其次,让我们看一个int &a = 1,这句话会导致error: non-const lvalue reference to type ‘double’ cannot bind to a value of unrelated type ‘int’
        1. 在编译器中就报错原因: That is because a temporary can not bind to a non-const reference.
        2. 可以更改为const int &a = 1,就可以正常使用了
      3. 同样的道理Complex& Complex::operator+ (const Complex& c) const这样的写法等同于int &a = 1
      4. 需要我们改为const Complex& Complex::operator+ (const Complex& c) const
      5. 现在有两个关键现象:
        1. 使用了引用作为返回值,依然不较少临时变量的生成!
        2. Complex c = a + b;这个语句中a+b这个步骤,产生的临时变量在执行=重载函数之前就被析构了!
        3. 在下面的程序中可以看出来
          1
          2
          3
          4
          Complex::Complex(double r, double i)//执行+
          Complex::~Complex()//执行+
          Complex::Complex(const Complex& c)//执行=
          real value is 6.95313e-310 image value is 2.16112e-314

封装类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#pragma once

#include <iostream>
using namespace std;

class Complex
{
public:
Complex(); // 默认构造函数
Complex(double r, double i); // 构造函数
virtual ~Complex(); // 析构函数
Complex(const Complex& x); // 拷贝构造
Complex& operator=(const Complex &c); // =号运算符


double GetReal( ) const { return _real; }
void SetReal(double d) { _real = d; }
double GetImage() const { return _image; }
void SetImage(double i) { _image = i; }

// 运算符重载
Complex operator+(const Complex &c) const;
Complex& operator+=(const Complex &c);
Complex operator-(const Complex &c) const;
Complex& operator-=(const Complex &c);
Complex operator*(const Complex &c) const;
Complex& operator*=(const Complex &c);
Complex operator/(const Complex &c) const;
Complex& operator/=(const Complex &c);

bool operator==(const Complex &c) const;
bool operator!=(const Complex &c) const;
bool operator>(const Complex &c) const;
bool operator>=(const Complex &c) const;
bool operator<(const Complex &c) const;
bool operator<=(const Complex &c) const;


// 前置和后置++
Complex& operator++(); //前置++
Complex operator++(int); //后置++
Complex& operator--(); //前置--
Complex operator--(int); //后置--

//protected:

friend ostream& operator<<(ostream& os, const Complex &x);
friend istream& operator>>(istream& is, Complex &x);

private:
double _real; // 复数的实部
double _image; // 复数的虚部
};

附录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#include "stdafx.h"

Complex::Complex()
{
_real = 0.0;
_image = 0.0;
cout << "Complex::Complex()" << endl;
}

Complex::Complex(double r, double i)
{
_real = r;
_image = i;
cout << "Complex::Complex(double r, double i)" << endl;
}

Complex::Complex(const Complex& c)
{
_real = c._real;
_image = c._image;
cout << "Complex::Complex(const Complex& c)" << endl;
}

Complex& Complex::operator= (const Complex& c)
{
if (this != &c)
{
_real = c._real;
_image = c._image;
}
return *this;
}

Complex::~Complex()
{
_real = _image = 0.0;
cout << "Complex::~Complex()" << endl;
}

Complex Complex::operator+ (const Complex& c) const
{
//Complex tmp;
//tmp._real = _real + x._real;
//tmp._image = _image + x._image;
//return tmp;

return Complex(_real + c._real, _image + c._image);
}


Complex& Complex::operator+= (const Complex& c)
{
_real += c._real;
_image += c._image;

return *this;
}

Complex Complex::operator-(const Complex &c) const
{
return Complex(_real - c._real, _image - c._image);
}

Complex& Complex::operator-=(const Complex &c)
{
_real -= c._real;
_image -= c._image;

return *this;
}

Complex Complex::operator*(const Complex &c) const
{
return Complex(_real*c._real - _image*c._image, _real*c._image + _image*c._real);
}

Complex& Complex::operator*=(const Complex &c)
{
Complex tmp(*this); //拷贝构造函数
_real = tmp._real*c._real - _image*c._image;
_image = tmp._real*c._image + tmp._image*c._real;
return *this;
}

Complex Complex::operator/(const Complex &c) const
{
double t = c._real*c._real + c._image*c._image;
return Complex((_real*c._real - _image*(-c._image)) / t, (_real*(-c._image) + _image*c._real) / t);
}

Complex& Complex::operator/=(const Complex &c)
{
Complex tmp(*this); //拷贝构造函数
double t = c._real*c._real + c._image*c._image;
_real = (tmp._real*c._real - tmp._image*(-c._image)) / t;
_image = (tmp._real*(-c._image) + tmp._image*c._real) / t;
return *this;
}

bool Complex::operator==(const Complex& c) const
{
return (_real == c._real) && (_image == c._image);
}

bool Complex::operator!=(const Complex& c) const
{
return !( (_real == c._real) && (_image == c._image) );
}

bool Complex::operator>(const Complex &c) const
{
return (_real > c._real) && (_image > c._image);
}

bool Complex::operator>=(const Complex &c) const
{
return (_real >= c._real) && (_image >= c._image);
}

bool Complex::operator<(const Complex &c) const
{
return (_real < c._real) && (_image < c._image);
}

bool Complex::operator<=(const Complex &c) const
{
return (_real <= c._real) && (_image <= c._image);
}


Complex& Complex::operator++ () // 前置++
{
_real++;
_image++;
return *this;
}

Complex Complex::operator++ (int) // 后置++
{
//Complex tmp(*this);
//_real++;
//_image++;
//return tmp;
return Complex(_real++, _image++);
}

Complex& Complex::operator--() //前置--
{
_real--;
_image--;
return *this;
}

Complex Complex::operator--(int) //后置--
{
return Complex(_real--, _image--);
}

ostream& operator<<(ostream& os, const Complex &x)
{
os << "real value is " << x._real << " image value is " << x._image;
return os;
}

istream& operator >> (istream& is, Complex &x)
{
is >> x._real >> x._image;
return is;
}