【C++第八课】---操作符重载上

来源:互联网 发布:浙江软件企业行业协会 编辑:程序博客网 时间:2024/06/07 19:23

一、关于C和C++标准库的使用

我们都知道C++为了向下兼容C,和多库都是基于C来开发的,那么对于C++的库的使用需要注意什么地方呢?

1、C++标准库并不是C++语言的一部分
2、C++ 标准库是由C++语言编写而成的类库和函数的集合 
3、C++标准库中定义的类和对象都位于std命名空间中 
4、C++标准库的头文件都不带.h 后缀
5、C++ 标准库涵盖了C库的功能
6、C库中<name.h>头文件对应 头文件对应C++ 中的<cname>

7、C++标准库预定义了多数常用的数据结构,如:字符串, 链表,队列,栈等。

下面举两个例子说明使用C库和C++库的区别

#include <cstdio>//使用C++标准库int main(int argc,char** argv){printf("This is a example !!\n");return 0;}

#include <iostream>//使用C++标准库using namespace std;int main(int argc,char** argv){cout<<"This is a example !!"<<endl;return 0;}


二、利用操作符的重载实现复数的加减

实例一----函数实现复数加法

#include <iostream>using namespace std;struct Complex{int a;int b;Complex(int i = 0,int j = 0){a = i;b = j;}};Complex add(const Complex& c1,const Complex& c2){Complex ret;ret.a = c1.a + c2.a;ret.b = c2.b + c2.b;return ret;}int main(int argc,char** argv){Complex a(1,2);Complex b(1,2);Complex c = add(a,b);cout<<"c.a = "<<c.a<<endl;cout<<"c.b = "<<c.b<<endl;return 0;}



说明:上述使用常引用的两个好处

1.能够提升代码执行效率

2.避免被函数体外修改

我们看到上述实现复数相加使用的是函数,那么,我们能不能直接用‘+’来实现呢?当然是肯定的,这里就引入函数的重载了。

操作符的重载实质上就是函数的重载,那么。我们如何利用函数重载来实现操作符的重载呢?

1、C++中通过operator关键字可以利用函数扩展操作符
2、operator的本质是通过函数重载实现操作符重载

下面请看我们函数如何修改

Complex operator+ (const Complex& c1,const Complex& c2){Complex ret;ret.a = c1.a + c2.a;ret.b = c2.b + c2.b;return ret;}


这时候我们得到一个这样的程序:

#include <iostream>using namespace std;struct Complex{int a;int b;Complex(int i = 0,int j = 0){a = i;b = j;}};Complex operator+ (const Complex& c1,const Complex& c2){Complex ret;ret.a = c1.a + c2.a;ret.b = c2.b + c2.b;return ret;}int main(int argc,char** argv){Complex a(1,2);Complex b(1,2);Complex c = a + b;cout<<"c.a = "<<c.a<<endl;cout<<"c.b = "<<c.b<<endl;return 0;}



此时的代码和上面的程序红色部分为改动部分,但是当我们编译运行后,能够得到相同的结果,到这里为止,我们就初步的实现了操作符的重载

下面我们还可以对其进行改进!

三、operator操作能够作用类么?

这个问题的答案是肯定的。下面我们改进一下,将struct改为标准的class,代码如下:

#include <iostream>using namespace std;class Complex{private:int a;int b;public:Complex(int i = 0,int j = 0){a = i;b = j;}friend Complex operator+ (const Complex& c1,const Complex& c2);friend void print(const Complex& c);};void print(const Complex& c){cout<<"c.a = "<<c.a<<endl;cout<<"c.b = "<<c.b<<endl;}Complex operator+ (const Complex& c1,const Complex& c2){Complex ret;ret.a = c1.a + c2.a;ret.b = c2.b + c2.b;return ret;}int main(int argc,char** argv){Complex a(1,2);Complex b(1,2);Complex c = a + b;print(c);return 0;}




注意上面红色部分,我为了能够访问到私有成员,定义了两个友元函数,这样打印的结果与上述程序最终的打印结果是一样的

但是相信大家会发现这种方法比较复杂,需要定义两个友元函数(注意:友元函数不是成员函数),那么我们有没有改进的方

法呢?  

简单,这里我们对<<左移操作符进行重载就行

四、如何对左移操作符进行重载呢?

首先,我们得明白左移右移的参数和对应的表达式是怎样的。

例如:

表达式:cout<<a<<endl;

函数    :ostream& operator<< (ostream& out,const Complex& c)

那么 cout就是对应的第一个参数,a就表示第二个参数。

等价于 ==  operator<<(cout,a);   

请仔细分析为什么返回值为ostream &类型。

具体实例如下:

#include <iostream>using namespace std;class Complex{private:int a;int b;public:Complex(int i = 0,int j = 0){a = i;b = j;}friend Complex operator+ (const Complex& c1,const Complex& c2);friend ostream& operator<< (ostream& out,const Complex& c);};Complex operator+ (const Complex& c1,const Complex& c2){Complex ret;ret.a = c1.a + c2.a;ret.b = c2.b + c2.b;return ret;}ostream& operator<< (ostream& out,const Complex& c){out<<c.a<<" + "<<c.b<<"i";return out;}int main(int argc,char** argv){Complex a(1,2);Complex b(1,2);Complex c = a + b;cout<<a<<endl;cout<<b<<endl;cout<<c<<endl;return 0;}



打印内容如下:

1 + 2i
1 + 2i
2 + 4i

 五、再次引入问题

通过operator operator关键字能够将操作符定义为全局函数,而操作符重载的本质就是函数重载

那么,类的成员函数是否可以作为操作符重载的函数呢?

答案是肯定的。

类成员函数实现操作符重载的一个实例

Complex Complex::operator+ (const Complex& c2){Complex ret;ret.a = a + c2.a;ret.b = b + c2.b;return ret;}



千万千万要注意的是:

1、用成员函数重载的操作符比全局操作符重载函数少一个参数,即左操作数。
2、不需要使用friend关键字  

否则会报错。

这是为什么呢?

因为第一个参数会调用this指针,用this指针指向成员变量的。

所以如下程序也是没有问题的

#include <iostream>using namespace std;class Complex{private:int a;int b;public:Complex(int i = 0,int j = 0){a = i;b = j;}Complex operator+ (const Complex& c2);friend ostream& operator<< (ostream& out,const Complex& c);};Complex Complex::operator+ (const Complex& c2){Complex ret;ret.a = a + c2.a;ret.b = b + c2.b;return ret;}ostream& operator<< (ostream& out,const Complex& c){out<<c.a<<" + "<<c.b<<"i";return out;}int main(int argc,char** argv){Complex a(1,2);Complex b(1,2);Complex c = a + b;cout<<a<<endl;cout<<b<<endl;cout<<c<<endl;return 0;}



还有一个需要注意的地方:

1、当无法修改左操作数的类时,使用全局函数进行重载
2、=, [], ()和->操作符只能通过成员函数进行重载
待续。。







原创粉丝点击