没有输出的输入是不完整的

0%

Class-without-pointer-Complex-Houjie-Bilibili

在Bilibili跟着侯捷老师学C++系列第一篇,不带指针的类Complex类。
人生得遇良师,实属大幸,侯捷老师就属于这种老师!!

因为C++的效率是最高的,所以对于C++自己一定要好好掌握,个人看法,你如果能学会C++,其他语言都将不在话下。然后刚好碰到一个非常好的教程,有一位非常棒的老师-侯捷老师,有一个好的平台-Bilibili,还有非常好的训练场地——leetcode,所以此时不学什么时候学呢?

教程

侯捷C++手把手教学(上),适合新手

代码文件

Complex.hpp

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
#ifndef Complex_hpp
#define Complex_hpp

#include <stdio.h>
#include <iostream>
class Complex{
public:
Complex(double r = 0, double i = 0) : re(r), im(i){}
Complex& operator += (const Complex&);
double real() const {return re;}
double imag() const {return im;}

private:
double re,im;

friend Complex& _doapl(Complex*, const Complex&);
};

#endif /* Complex_hpp */

inline Complex& Complex::operator += (const Complex& c){
return _doapl(this,c);
}

inline Complex& _doapl(Complex* ths,const Complex& c){
ths->im += c.im;
ths->re += c.re;
return *ths;
}

inline double real(const Complex& r){
return r.real();
}

inline double imag(const Complex& r){
return r.imag();
}

inline Complex operator +(const Complex& r1,const Complex r2){
return Complex(real(r1)+real(r2), imag(r1)+imag(r2));
}

inline Complex operator + (const Complex& r1, double d){
return Complex(real(r1)+d,imag(r1));
}

inline Complex operator + (double d,const Complex& r1){
return Complex(real(r1)+d, imag(r1));
}

std::ostream& operator << (std::ostream& os,const Complex& c){
return os<<"("<<real(c)<<","<<imag(c)<<")";
}

Complex.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include "Complex.hpp"

using namespace std;
int main(){
Complex c1(2,3);
Complex c2;
// 测试输出
cout<<c1<<endl;
// 测试连续输出
cout<<c1<<c1<<endl;
// 测试 +=
c1 += c2;
cout<< c1<<endl;
// 测试+运算
cout<< c1+2<<endl;
}

result

1
2
3
4
(2,3)
(2,3)(2,3)
(2,3)
(4,3)

细节剖析

  1. 首先是要有一个防卫式声明。
1
2
3
4
#ifndef Complex_hpp
#define Complex_hpp

#endif /* Complex_hpp */

它的作用在于当我们写的类被其他人通过导入头文件引用的时候不会重复引用。
2. 类的数据不出意外都要写在private部分,也就是下面的部分。而方法一般都是写在public部分。

1
2
private:
double re,im;
  1. 函数的要不要加const关键字,如果没有更改类属性的值,都要加上。
1
double real() const {return re;}
  1. 函数参数要不要加const关键字,如果我们不想这个参数在方法中被修改,那么就加上。
1
2
3
inline double real(const Complex& r){
return r.real();
}
  1. 考虑是返回值是传值还是传引用。尽量都传引用,这样可以极大的提高效率。但是当返回的值是一个局部变量的时候,要记得通过值进行返回。
  2. 在重载操作符的时候,考虑返回值要考虑到会不会有多重使用,然后再考虑是要无返回还是返回一个引用值。
1
2
3
std::ostream& operator << (std::ostream& os,const Complex& c){
return os<<"("<<real(c)<<","<<imag(c)<<")";
}
  1. 当重载运算符的时候要声明其为全局函数。
  2. 构造函数可以通过initialization list来进行初始化。
1
Complex(double r = 0, double i = 0) : re(r), im(i){}
  1. 传递者无需知道接收者是以什么形式传递数据。传递者只需要传过去即可。但是如果以reference进行传递效率会高一点。
  2. 友元函数可以直接访问私有数据。