Go最新【C++学习笔记】C+(6),面试Golang开发自我介绍

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取


它的作用是使一个整数和一个复数相加。


另外,将运算符重载函数作为全局函数时,一般都需要在类中将该函数声明为友元函数。原因很简单,该函数大部分情况下都需要使用类的 private 成员。


上节的最后一个例子中,我们在全局范围内重载了`+`号,并在 complex 类中将运算符重载函数声明为友元函数,因为该函数使用到了 complex 类的 m\_real 和 m\_imag 两个成员变量,它们都是 private 属性的,默认不能在类的外部访问。


6. 箭头运算符`->`、下标运算符`[ ]`、函数调用运算符`( )`、赋值运算符`=`只能以成员函数的形式重载。


## C++重载数学运算符(实例演示)


四则运算符(+、-、*、/、+=、-=、*=、/=)和关系运算符(>、<、<=、>=、==、!=)都是数学运算符,它们在实际开发中非常常见,被重载的几率也很高,并且有着相似的重载格式。本节以复数类 Complex 为例对它们进行重载,重在演示运算符重载的语法以及规范。


复数能够进行完整的四则运算,但不能进行完整的关系运算:我们只能判断两个复数是否相等,但不能比较它们的大小,所以不能对 >、<、<=、>= 进行重载。下面是具体的代码:



#include
#include
using namespace std;
//复数类
class Complex{
public: //构造函数
Complex(double real = 0.0, double imag = 0.0): m_real(real), m_imag(imag){ }
public: //运算符重载
//以全局函数的形式重载
friend Complex operator+(const Complex &c1, const Complex &c2);
friend Complex operator-(const Complex &c1, const Complex &c2);
friend Complex operator*(const Complex &c1, const Complex &c2);
friend Complex operator/(const Complex &c1, const Complex &c2);
friend bool operator==(const Complex &c1, const Complex &c2);
friend bool operator!=(const Complex &c1, const Complex &c2);
//以成员函数的形式重载
Complex & operator+=(const Complex &c);
Complex & operator-=(const Complex &c);
Complex & operator*=(const Complex &c);
Complex & operator/=(const Complex &c);
public: //成员函数
double real() const{ return m_real; }
double imag() const{ return m_imag; }
private:
double m_real; //实部
double m_imag; //虚部
};
//重载+运算符
Complex operator+(const Complex &c1, const Complex &c2){
Complex c;
c.m_real = c1.m_real + c2.m_real;
c.m_imag = c1.m_imag + c2.m_imag;
return c;
}
//重载-运算符
Complex operator-(const Complex &c1, const Complex &c2){
Complex c;
c.m_real = c1.m_real - c2.m_real;
c.m_imag = c1.m_imag - c2.m_imag;
return c;
}
//重载运算符 (a+bi) * (c+di) = (ac-bd) + (bc+ad)i
Complex operator
(const Complex &c1, const Complex &c2){
Complex c;
c.m_real = c1.m_real * c2.m_real - c1.m_imag * c2.m_imag;
c.m_imag = c1.m_imag * c2.m_real + c1.m_real * c2.m_imag;
return c;
}
//重载/运算符 (a+bi) / (c+di) = [(ac+bd) / (c²+d²)] + [(bc-ad) / (c²+d²)]i
Complex operator/(const Complex &c1, const Complex &c2){
Complex c;
c.m_real = (c1.m_realc2.m_real + c1.m_imagc2.m_imag) / (pow(c2.m_real, 2) + pow(c2.m_imag, 2));
c.m_imag = (c1.m_imagc2.m_real - c1.m_realc2.m_imag) / (pow(c2.m_real, 2) + pow(c2.m_imag, 2));
return c;
}
//重载运算符
bool operator
(const Complex &c1, const Complex &c2){
if( c1.m_real == c2.m_real && c1.m_imag == c2.m_imag ){
return true;
}else{
return false;
}
}
//重载!=运算符
bool operator!=(const Complex &c1, const Complex &c2){
if( c1.m_real != c2.m_real || c1.m_imag != c2.m_imag ){
return true;
}else{
return false;
}
}
//重载+=运算符
Complex & Complex::operator+=(const Complex &c){
this->m_real += c.m_real;
this->m_imag += c.m_imag;
return this;
}
//重载-=运算符
Complex & Complex::operator-=(const Complex &c){
this->m_real -= c.m_real;
this->m_imag -= c.m_imag;
return this;
}
//重载
=运算符
Complex & Complex::operator
=(const Complex &c){
this->m_real = this->m_real * c.m_real - this->m_imag * c.m_imag;
this->m_imag = this->m_imag * c.m_real + this->m_real * c.m_imag;
return this;
}
//重载/=运算符
Complex & Complex::operator/=(const Complex &c){
this->m_real = (this->m_real
c.m_real + this->m_imagc.m_imag) / (pow(c.m_real, 2) + pow(c.m_imag, 2));
this->m_imag = (this->m_imag
c.m_real - this->m_real*c.m_imag) / (pow(c.m_real, 2) + pow(c.m_imag, 2));
return *this;
}
int main(){
Complex c1(25, 35);
Complex c2(10, 20);
Complex c3(1, 2);
Complex c4(4, 9);
Complex c5(34, 6);
Complex c6(80, 90);

Complex c7 = c1 + c2;
Complex c8 = c1 - c2;
Complex c9 = c1 * c2;
Complex c10 = c1 / c2;
cout<<"c7 = "<<c7.real()<<" + "<<c7.imag()<<"i"<<endl;
cout<<"c8 = "<<c8.real()<<" + "<<c8.imag()<<"i"<<endl;
cout<<"c9 = "<<c9.real()<<" + "<<c9.imag()<<"i"<<endl;
cout<<"c10 = "<<c10.real()<<" + "<<c10.imag()<<"i"<<endl;

c3 += c1;
c4 -= c2;
c5 *= c2;
c6 /= c2;
cout<<"c3 = "<<c3.real()<<" + "<<c3.imag()<<"i"<<endl;
cout<<"c4 = "<<c4.real()<<" + "<<c4.imag()<<"i"<<endl;
cout<<"c5 = "<<c5.real()<<" + "<<c5.imag()<<"i"<<endl;
cout<<"c6 = "<<c6.real()<<" + "<<c6.imag()<<"i"<<endl;

if(c1 == c2){
    cout<<"c1 == c2"<<endl;
}
if(c1 != c2){
    cout<<"c1 != c2"<<endl;
}

return 0;

}


运行结果:  
 c7 = 35 + 55i  
 c8 = 15 + 15i  
 c9 = -450 + 850i  
 c10 = 1.9 + -0.3i  
 c3 = 26 + 37i  
 c4 = -6 + -11i  
 c5 = 220 + 4460i  
 c6 = 5.2 + 1.592i  
 c1 != c2


需要注意的是,我们以全局函数的形式重载了 +、-、*、/、==、!=,以成员函数的形式重载了 +=、-=、*=、/=,而且应该坚持这样做,不能一股脑都写作成员函数或者全局函数,具体原因我们将在下节《[到底以成员函数还是全局函数(友元函数)的形式重载运算符]( )》讲解。


## 到底以成员函数还是全局函数(友元函数)的形式重载运算符


在上节的例子中,我们以全局函数的形式重载了 +、-、*、/、==、!=,以成员函数的形式重载了 +=、-=、*=、/=,而没有一股脑都写成全局函数或者成员函数,这样做是有原因的,这节我们就来分析一下。


### 简单地了解转换构造函数


在分析以前,我们先来了解一个概念,叫做「转换构造函数」。这个概念将会在《[C++转换构造函数]( )》一节中深入讲解,但是为了搞清成员函数和全局函数的区别,本节我们有必要提前了解一下。


请大家先看下面的例子:



#include
using namespace std;
//复数类
class Complex{
public:
Complex(): m_real(0.0), m_imag(0.0){ }
Complex(double real, double imag): m_real(real), m_imag(imag){ }
Complex(double real): m_real(real), m_imag(0.0){ } //转换构造函数
public:
friend Complex operator+(const Complex &c1, const Complex &c2);
public:
double real() const{ return m_real; }
double imag() const{ return m_imag; }
private:
double m_real; //实部
double m_imag; //虚部
};
//重载+运算符
Complex operator+(const Complex &c1, const Complex &c2){
Complex c;
c.m_real = c1.m_real + c2.m_real;
c.m_imag = c1.m_imag + c2.m_imag;
return c;
}
int main(){
Complex c1(25, 35);
Complex c2 = c1 + 15.6;
Complex c3 = 28.23 + c1;
cout<<c2.real()<<" + “<<c2.imag()<<“i”<<endl;
cout<<c3.real()<<” + "<<c3.imag()<<“i”<<endl;

return 0;

}


运行结果:  
 40.6 + 35i  
 53.23 + 35i


请读者留意第 30、31 行代码,它说明 Complex 类型可以和 double 类型相加,这很奇怪,因为我们并没有对针对这两个类型重载 +,这究竟是怎么做到的呢?


其实,编译器在检测到 Complex 和 double(小数默认为 double 类型)相加时,会先尝试将 double 转换为 Complex,或者反过来将 Complex 转换为 double(只有类型相同的数据才能进行 + 运算),如果都转换失败,或者都转换成功(产生了二义性),才报错。本例中,编译器会先通过构造函数`Complex(double real);`将 double 转换为 Complex,再调用重载过的 + 进行计算,整个过程类似于下面的形式:  
 ![img](https://img-blog.csdnimg.cn/img_convert/c63ac3b3ff00c92ff140c6c7c1fccfb2.png)  
 也就是说,小数被转换成了匿名的 Complex 对象。在这个转换过程中,构造函数`Complex(double real);`起到了至关重要的作用,如果没有它,转换就会失败,Complex 也不能和 double 相加。


`Complex(double real);`在作为普通构造函数的同时,还能将 double 类型转换为 Complex 类型,集合了“构造函数”和“类型转换”的功能,所以被称为「转换构造函数」。换句话说,转换构造函数用来将其它类型(可以是 bool、int、double 等基本类型,也可以是数组、指针、结构体、类等构造类型)转换为当前类类型。


作为了解,这里不再对转换构造函数阐述更多细节,后续将在《[C++转换构造函数]( )》一节中深入讲解。


### 为什么要以全局函数的形式重载 +


上面的例子中,我们定义的`operator+`是一个全局函数(一个友元函数),而不是成员函数,这样做是为了保证 + 运算符的操作数能够被对称的处理;换句话说,小数(double 类型)在 + 左边和右边都是正确的。第 30 行代码中,15.6 在 + 的右边,第 31 行代码中,28.23 在 + 的左边,它们都能够被顺利地转换为 Complex 类型,所以不会出错。


如果将`operator+`定义为成员函数,根据“+ 运算符具有左结合性”这条原则,`Complex c2 = c1 + 15.6;`会被转换为下面的形式:


Complex c2 = c1.operator+(Complex(15.6));


这就是通过对象调用成员函数,是正确的。而对于`Complex c3 = 28.23 + c1;`,编译器会尝试转换为不同的形式:


Complex c3 = (28.23).operator+(c1);


很显然这是错误的,因为 double 类型并没有以成员函数的形式重载 +。


也就是说,以成员函数的形式重载 +,只能计算`c1 + 15.6`,不能计算`28.23 + c1`,这是不对称的


有读者可能会问,编译器明明可以把 28.23 先转换成 Complex 类型再相加呀,也就是下面的形式:


Complex c3 = Complex(28.23).operator+(c1);


为什么就是不转换呢?没错,编译器不会转换,原因在于,C++ 只会对成员函数的参数进行类型转换,而不会对调用成员函数的对象进行类型转换。以下面的语句为例:


obj.func(params);


编译器不会尝试对 obj 进行任何类型转换,它有 func() 成员函数就调用,没有就报错。而对于实参 params,编译器会“拼命地”将它转换为形参的类型。


### 为什么要以成员函数的形式重载 +=


我们首先要明白,运算符重载的初衷是给类添加新的功能,方便类的运算,它作为类的成员函数是理所应当的,是首选的。不过,类的成员函数不能对称地处理数据,程序员必须在(参与运算的)所有类型的内部都重载当前的运算符。以上面的情况为例,我们必须在 Complex 和 double 内部都重载 + 运算符,这样做不但会增加运算符重载的数目,还要在许多地方修改代码,这显然不是我们所希望的,所以 C++ 进行了折中,允许以全局函数(友元函数)的形式重载运算符。


C++ 创始人 Bjarne Stroustrup 也曾考虑过为内部类型(bool、int、double 等)定义额外运算符的问题,但后来还是放弃了这种想法,因为 Bjarne Stroustrup 不希望改变现有规则:任何类型(无论是内部类型还是用户自定义类型)都不能在其定义完成以后再增加额外的操作。这里还有另外的一个原因,C内部类型之间的转换已经够肮脏了,决不能再向里面添乱。而通过成员函数为已存在的类型提供混合运算的方式,从本质上看,比我们所采用的全局函数(友元函数)加转换构造函数的方式还要肮脏许多。


采用全局函数能使我们定义这样的运算符,它们的参数具有逻辑的对称性。与此相对应的,把运算符定义为成员函数能够保证在调用时对第一个(最左的)运算对象不出现类型转换,也就是上面提到的「C++ 不会对调用成员函数的对象进行类型转换」。


总起来说,有一部分运算符重载既可以是成员函数也可以是全局函数,虽然没有一个必然的、不可抗拒的理由选择成员函数,但我们应该优先考虑成员函数,这样更符合运算符重载的初衷;另外有一部分运算符重载必须是全局函数,这样能保证参数的对称性;除了 C++ 规定的几个特定的运算符外,暂时还没有发现必须以成员函数的形式重载的运算符。



> 
> C++ 规定,箭头运算符`->`、下标运算符`[ ]`、函数调用运算符`( )`、赋值运算符`=`只能以成员函数的形式重载。
> 
> 
> 


## C++重载>>和<<(输入和输出运算符)详解


在[C++]( )中,标准库本身已经对左移运算符`<<`和右移运算符`>>`分别进行了重载,使其能够用于不同数据的输入输出,但是输入输出的对象只能是 C++ 内置的数据类型(例如 bool、int、double 等)和标准库所包含的类类型(例如 string、complex、ofstream、ifstream 等)。


如果我们自己定义了一种新的数据类型,需要用输入输出运算符去处理,那么就必须对它们进行重载。本节以前面的 complex 类为例来演示输入输出运算符的重载。



> 
> 其实 C++ 标准库已经提供了 complex 类,能够很好地支持复数运算,但是这里我们又自己定义了一个 complex 类,这样做仅仅是为了教学演示。
> 
> 
> 


本节要达到的目标是让复数的输入输出和 int、float 等基本类型一样简单。假设 num1、num2 是复数,那么输出形式就是:


cout<<num1<<num2<<endl;


输入形式就是:


cin>>num1>>num2;


cout 是 ostream 类的对象,cin 是 istream 类的对象,要想达到这个目标,就必须以全局函数(友元函数)的形式重载`<<`和`>>`,否则就要修改标准库中的类,这显然不是我们所期望的。


### 重载输入运算符>>


下面我们以全局函数的形式重载`>>`,使它能够读入两个 double 类型的数据,并分别赋值给复数的实部和虚部:



istream & operator>>(istream &in, complex &A){
in >> A.m_real >> A.m_imag;
return in;
}


istream 表示输入流,cin 是 istream 类的对象,只不过这个对象是在标准库中定义的。之所以返回 istream 类对象的引用,是为了能够连续读取复数,让代码书写更加漂亮,例如:


complex c1, c2;  
 cin>>c1>>c2;


如果不返回引用,那就只能一个一个地读取了:


complex c1, c2;  
 cin>>c1;  
 cin>>c2;


另外,运算符重载函数中用到了 complex 类的 private 成员变量,必须在 complex 类中将该函数声明为友元函数:


friend istream & operator>>(istream & in , complex &a);


`>>`运算符可以按照下面的方式使用:


complex c;  
 cin>>c;


当输入`1.45 2.34↙`后,这两个小数就分别成为对象 c 的实部和虚部了。`cin>> c;`这一语句其实可以理解为:


operator<<(cin , c);


### 重载输出运算符<<


同样地,我们也可以模仿上面的形式对输出运算符`>>`进行重载,让它能够输出复数,请看下面的代码:



ostream & operator<<(ostream &out, complex &A){
out << A.m_real <<" + “<< A.m_imag <<” i ";
return out;
}


ostream 表示输出流,cout 是 ostream 类的对象。由于采用了引用的方式进行参数传递,并且也返回了对象的引用,所以重载后的运算符可以实现连续输出。


为了能够直接访问 complex 类的 private 成员变量,同样需要将该函数声明为 complex 类的友元函数:


friend ostream & operator<<(ostream &out, complex &A);


### 综合演示


结合输入输出运算符的重载,重新实现 complex 类:



#include
using namespace std;
class complex{
public:
complex(double real = 0.0, double imag = 0.0): m_real(real), m_imag(imag){ };
public:
friend complex operator+(const complex & A, const complex & B);
friend complex operator-(const complex & A, const complex & B);
friend complex operator*(const complex & A, const complex & B);
friend complex operator/(const complex & A, const complex & B);
friend istream & operator>>(istream & in, complex & A);
friend ostream & operator<<(ostream & out, complex & A);
private:
double m_real; //实部
double m_imag; //虚部
};
//重载加法运算符
complex operator+(const complex & A, const complex &B){
complex C;
C.m_real = A.m_real + B.m_real;
C.m_imag = A.m_imag + B.m_imag;
return C;
}
//重载减法运算符
complex operator-(const complex & A, const complex &B){
complex C;
C.m_real = A.m_real - B.m_real;
C.m_imag = A.m_imag - B.m_imag;
return C;
}
//重载乘法运算符
complex operator*(const complex & A, const complex &B){
complex C;
C.m_real = A.m_real * B.m_real - A.m_imag * B.m_imag;
C.m_imag = A.m_imag * B.m_real + A.m_real * B.m_imag;
return C;
}
//重载除法运算符
complex operator/(const complex & A, const complex & B){
complex C;
double square = A.m_real * A.m_real + A.m_imag * A.m_imag;
C.m_real = (A.m_real * B.m_real + A.m_imag * B.m_imag)/square;
C.m_imag = (A.m_imag * B.m_real - A.m_real * B.m_imag)/square;
return C;
}
//重载输入运算符
istream & operator>>(istream & in, complex & A){
in >> A.m_real >> A.m_imag;
return in;
}
//重载输出运算符
ostream & operator<<(ostream & out, complex & A){
out << A.m_real <<" + “<< A.m_imag <<” i ";;
return out;
}
int main(){
complex c1, c2, c3;
cin>>c1>>c2;
c3 = c1 + c2;
cout<<"c1 + c2 = "<<c3<<endl;
c3 = c1 - c2;
cout<<"c1 - c2 = "<<c3<<endl;
c3 = c1 * c2;
cout<<"c1 * c2 = "<<c3<<endl;
c3 = c1 / c2;
cout<<"c1 / c2 = "<<c3<<endl;
return 0;
}


运行结果:  
 2.4 3.6↙  
 4.8 1.7↙  
 c1 + c2 = 7.2 + 5.3 i  
 c1 - c2 = -2.4 + 1.9 i  
 c1 \* c2 = 5.4 + 21.36 i  
 c1 / c2 = 0.942308 + 0.705128 i


## C++重载[](下标运算符)详解


[C++]( ) 规定,下标运算符`[ ]`必须以成员函数的形式进行重载。该重载函数在类中的声明格式如下:


返回值类型 & operator[ ] (参数);


或者:


const 返回值类型 & operator[ ] (参数) const;


使用第一种声明方式,`[ ]`不仅可以访问元素,还可以修改元素。使用第二种声明方式,`[ ]`只能访问而不能修改元素。在实际开发中,我们应该同时提供以上两种形式,这样做是为了适应 const 对象,因为[通过 const 对象只能调用 const 成员函数]( ),如果不提供第二种形式,那么将无法访问 const 对象的任何元素。


下面我们通过一个具体的例子来演示如何重载`[ ]`。我们知道,有些较老的编译器不支持[变长数组]( ),例如 VC6.0、VS2010 等,这有时候会给编程带来不便,下面我们通过自定义的 Array 类来实现变长数组。



#include
using namespace std;
class Array{
public:
Array(int length = 0);
~Array();
public:
int & operator[](int i);
const int & operator[](int i) const;
public:
int length() const { return m_length; }
void display() const;
private:
int m_length; //数组长度
int *m_p; //指向数组内存的指针
};
Array::Array(int length): m_length(length){
if(length == 0){
m_p = NULL;
}else{
m_p = new int[length];
}
}
Array::~Array(){
delete[] m_p;
}
int& Array::operator[](int i){
return m_p[i];
}
const int & Array::operator[](int i) const{
return m_p[i];
}
void Array::display() const{
for(int i = 0; i < m_length; i++){
if(i == m_length - 1){
cout<<m_p[i]<<endl;
}else{
cout<<m_p[i]<<", ";
}
}
}
int main(){
int n;
cin>>n;
Array A(n);
for(int i = 0, len = A.length(); i < len; i++){
A[i] = i * 5;
}
A.display();

const Array B(n);
cout<<B[n-1]<<endl;  //访问最后一个元素

return 0;

}


运行结果:  
 5↙  
 0, 5, 10, 15, 20  
 33685536


重载`[ ]`运算符以后,表达式`arr[i]`会被转换为:


arr.operator;


需要说明的是,B 是 const 对象,如果 Array 类没有提供 const 版本的`operator[ ]`,那么第 60 行代码将报错。虽然第 60 行代码只是读取对象的数据,并没有试图修改对象,但是它调用了非 const 版本的`operator[ ]`,编译器不管实际上有没有修改对象,只要是调用了非 const 的成员函数,编译器就认为会修改对象(至少有这种风险)。


## C++重载++和–(自增和自减运算符)详解


自增`++`和自减`--`都是一元运算符,它的前置形式和后置形式都可以被重载。请看下面的例子:



#include
#include
using namespace std;
//秒表类
class stopwatch{
public:
stopwatch(): m_min(0), m_sec(0){ }
public:
void setzero(){ m_min = 0; m_sec = 0; }
stopwatch run(); // 运行
stopwatch operator++(); //++i,前置形式
stopwatch operator++(int); //i++,后置形式
friend ostream & operator<<( ostream &, const stopwatch &);
private:
int m_min; //分钟
int m_sec; //秒钟
};
stopwatch stopwatch::run(){
++m_sec;
if(m_sec == 60){
m_min++;
m_sec = 0;
}
return *this;
}
stopwatch stopwatch::operator++(){
return run();
}
stopwatch stopwatch::operator++(int n){
stopwatch s = *this;
run();
return s;
}
ostream &operator<<( ostream & out, const stopwatch & s){
out<<setfill(‘0’)<<setw(2)<<s.m_min<<“:”<<setw(2)<<s.m_sec;
return out;
}
int main(){
stopwatch s1, s2;
s1 = s2++;
cout << "s1: "<< s1 <<endl;
cout << "s2: "<< s2 <<endl;
s1.setzero();
s2.setzero();
s1 = ++s2;
cout << "s1: "<< s1 <<endl;
cout << "s2: "<< s2 <<endl;
return 0;
}


运行结果:  
 s1: 00:00  
 s2: 00:01  
 s1: 00:01  
 s2: 00:01


上面的代码定义了一个简单的秒表类,m\_min 表示分钟,m\_sec 表示秒钟,setzero() 函数用于秒表清零,run() 函数是用来描述秒针前进一秒的动作,接下来是三个运算符重载函数。


先来看一下 run() 函数的实现,run() 函数一开始让秒针自增,如果此时自增结果等于60了,则应该进位,分钟加1,秒针置零。


operator++() 函数实现自增的前置形式,直接返回 run() 函数运行结果即可。


operator++ (int n) 函数实现自增的后置形式,返回值是对象本身,但是之后再次使用该对象时,对象自增了,所以在该函数的函数体中,先将对象保存,然后调用一次 run() 函数,之后再将先前保存的对象返回。在这个函数中参数n是没有任何意义的,它的存在只是为了区分是前置形式还是后置形式。


![img](https://img-blog.csdnimg.cn/img_convert/3b0f014b0c6cf433bf85cd756d41d531.png)
![img](https://img-blog.csdnimg.cn/img_convert/5f50d5570e58e074b21f8d9e168c8083.png)
![img](https://img-blog.csdnimg.cn/img_convert/bf63b5f603a7378f606d02481ef95d43.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618658159)**

in 表示分钟,m\_sec 表示秒钟,setzero() 函数用于秒表清零,run() 函数是用来描述秒针前进一秒的动作,接下来是三个运算符重载函数。


先来看一下 run() 函数的实现,run() 函数一开始让秒针自增,如果此时自增结果等于60了,则应该进位,分钟加1,秒针置零。


operator++() 函数实现自增的前置形式,直接返回 run() 函数运行结果即可。


operator++ (int n) 函数实现自增的后置形式,返回值是对象本身,但是之后再次使用该对象时,对象自增了,所以在该函数的函数体中,先将对象保存,然后调用一次 run() 函数,之后再将先前保存的对象返回。在这个函数中参数n是没有任何意义的,它的存在只是为了区分是前置形式还是后置形式。


[外链图片转存中...(img-ZGhxsJOF-1715519152964)]
[外链图片转存中...(img-pEyxs1PJ-1715519152965)]
[外链图片转存中...(img-hPcMVfRN-1715519152965)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618658159)**

  • 14
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值