博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
细谈C++的运算符重载
阅读量:5885 次
发布时间:2019-06-19

本文共 4611 字,大约阅读时间需要 15 分钟。

hot3.png

什么是运算符重载?

      顾名思义就是将原本的操作符以我们的方式定义出来,方便我们使用。

为什么要进行运算符重载?

      简单的理由就是将减少程序员的工作量,首先先看一个简单的例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

class A{

public:

    A(int data):data(data){};

    void show(){

        cout << "data = " << data << endl;

    }   

private:

    int data;

};

int main(int ac, char *av[])

{

    A a1(100), a2(200);

 

    (a1+a2).show(); //请注意这一句我们可以这样吗?编译一下看看                                                                                            

    return 0;

}      

编译结果:

[root@anna-laptop day11]# cc.sh overload_operator.cpp 

========================   C++_program Compling  =====================       

overload_operator.cpp: In function ‘int main(intchar**)’:

overload_operator.cpp:17: error: no match for ‘operator+’ in ‘a1 + a2’

             ERROR g++ -o  overload_operator.cpp -g -lpthread

      这样的结果并不是我们想要的,我们只是想相加一下两个对象里面数据并且将结果显示出来,但是操作符“+”的左右两边的变量必须是内置变量类型。所以为了方便,我们可以为我们自定义类型的对象对操作符“+”进行运算符重载,进行如下更改:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

class A{

public:

    A(int data):data(data){};

    void show(){

        cout << "data = " << data << endl;

    }  

    // 运算符重载函数 

    A operator+(const A& a){ 

        return A(data + a.data);

    }   

private:

    int data;

};

int main(int ac, char *av[])

{

    A a1(100), a2(200);

 

    (a1+a2).show();

    return 0;

}

      如我们所愿,进行如上更改我们完成了直接让两个类对象进行直接相加,大大减少了程序员的工作量。下来我们细细谈一下运算符重载函数的具体内容:

 运算符重载函数的定义和调用分为两种:

       1、以友元函数定义

            定义格式: friend return_val   operatorOPT(type& name...);

            调用格式:operatorOPT(obj_list);

                             obj1 OPT obj2;

           友元不是成员,不能直接在友元函数中使用对象的成员变量,也不能使用this指针,所以在进行函数调用的时候,需要将对象的成员函数传进去。

      2、以成员函数函数定义

           定义格式:return_val   operatorOPT(type& name...);

                  注意:在使用成员函数进行调用的时候,如果使用对象的成员变量,不用将成员变量再传入函数中,直接在成员函数中使用就可以。

          调用格式:obj1.operatorOPT(obj2);

                           obj1 OPT obj2;

下面举例来进行说明:

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

class F{

public:

    F(int n = 0, int d = 1):n(n), d(d){}

    // 以成员函数对操作符进行重载

    F operator*(const F& o)const{

        return F(o.n * n, o.d * d); 

    }  

    // 以友元函数对操作符进行重载,友元函数的声明 

    friend F operator/(const F& obj1, const F& obj2);

private:

    int n;

    int d;

};

 

// 友元函数的定义

F operator/(const F& obj1, const F& obj2)

{

    return(obj1.n * obj2.d, obj1.d * obj2.n);

}

int main(int ac, char *av[])

{

    F f1(1,2);

    F f2(3,4);

    F f3;

     

    f3 = f1.operator*(f2);

    f3.show();

    (f1*f2).show();

    f3 = operator/(f1, f2);

    f3.show();

    (f1/f2).show();

     

    return 0;

}

在进行运算符重载的时候我们需要注意两个问题:

  1、在运算符的操作数,必须至少含有一个自定义类型的变量。

  2、尽量使用成员函数对运算符进行重载,但是有的运算符只能使用友元函数进行重载。

      比如对于"<<" 和“>>”的重载,如下:

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

class F{

public:

    F(int n = 0, int d = 1):n(n), d(d){}

    friend ostream& operator<<(ostream& os, const F& f){

        os << f.n << '/' << f.d;

        return os;

    }

    friend istream& operator>>(istream& is, F& f){

        char ch;

        is >> f.n >> ch >> f.d;

        return is;

    }

    F operator*(const F& o)const{

        return F(o.n * n, o.d * d);

    }

    friend F operator/(const F& obj1, const F& obj2);

private:

    int n;

    int d;

};

 

F operator/(const F& f1, const F& f2)

{

    return(f1.n * f2.d, f1.d * f2.n);

}

int main(int ac, char *av[])

{

    F f1(1,2);

    F f2(3,4);

 

    cout << f1 << "*" << f2 << "=" << f1*f2 << endl;

    cout << f1 << "/" << f2 << "=" << f1/f2 << endl;

    cout << "enter 2 number : \n";

    cin >> f1 >> f2;

    cout << "f1 = " << f1 << endl;

    cout << "f2 = " << f2 << endl;

     

    return 0;

}        

运行结果:

[root@anna-laptop overload_operator]# ./muldiv

[1/2]*[3/4]=[3/8]

[1/2]/[3/4]=[4/6]

enter 2 number : 

123 / 456

234/ 7645

f1 = [123/456]

f2 = [234/7645]

      以上的操作符全是对于双目运算符的重载,下面简单介绍几个单目运算符的例子,如"++"和"--"

因为++有前置++和后置++两种,--也是如此,对于前置++我们直接将++后的结果直接返回即可,对于后置++,为了方便区别于前置++,通常认为++后面仍然含有一个int类型的数组。进行如下操作:

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

class A{

public:

    A(int data = 0):data(data){}

    friend ostream& operator<<(ostream& os, const A& a){

        os << a.data;

        return os;

    }

    friend istream& operator>>(istream& is, A& a){

        is >> a.data;

        return is;

    }

    // 前置 ++;

    friend A& operator++(A& a){

         a.data += 10;

        return a;

    }

    // 前置 --

    A& operator--(){

        data -= 10;

        return *this;

    }

    // 后置 ++;

    friend A operator++(A& a, int){

        A old(a);

        a.data += 5;

        return old;

    }

    // 后置 --

    A operator--(int){

        A old(*this);

        data -= 5;

        return old;

    }

private:

    int data;

};

int main(int ac, char *av[])

{

    A a1(100);

    A a2(100);

 

    cout << "a1 = " << a1 << endl; 

    cout << "a2 = " << a2 << endl; 

    ++a1;

    --a2;

    cout << "++a1 = " << a1 << endl; 

    cout << "--a2 = " << a2 << endl; 

    cout << "a1++ = " << a1++ << endl; 

    cout << "a2-- = " << a2-- << endl; 

    cout << "a1 = " << a1 << endl; 

    cout << "a2 = " << a2 << endl; 

    return 0;

}

  当然还有以下操作符不能进行重载:

     1、三目运算符不能进行重载;

     2、"."成员运算符不能重载;

     3、成员指针运算符不能进行重载;

     4、"::"这是对于类的运算符,不能进行重载。

 

 

================= 以上就是对于运算符重载的介绍 =======================

 

免费学习更多精品课程,登录乐搏学院官网

或关注我们的官方微博,还有更多惊喜哦~

 

本文出自 “” 博客,请务必保留此出处

转载于:https://my.oschina.net/learnbo/blog/808976

你可能感兴趣的文章
C/C++ 多线程机制
查看>>
如何使用Core Text计算一段文本绘制在屏幕上之后的高度
查看>>
2010技术应用计划
查看>>
Winform开发框架之权限管理系统改进的经验总结(3)-系统登录黑白名单的实现...
查看>>
JavaScript高级程序设计--对象,数组(栈方法,队列方法,重排序方法,迭代方法)...
查看>>
【转】 学习ios(必看经典)牛人40天精通iOS开发的学习方法【2015.12.2
查看>>
在 ASP.NET MVC 中使用异步控制器
查看>>
SQL语句的执行过程
查看>>
详解Linux中Load average负载
查看>>
PHP遍历文件夹及子文件夹所有文件
查看>>
WinForm程序中两份mdf文件问题的解决
查看>>
程序计数器、反汇编工具
查看>>
Android N: jack server failed
查看>>
如何将lotus 通讯簿导入到outlook 2003中
查看>>
WinForm 应用程序中开启新的进程及控制
查看>>
js replace,正则截取字符串内容
查看>>
Thinkphp5笔记三:创建基类
查看>>
查询反模式 - GroupBy、HAVING的理解
查看>>
Android中EditText,Button等控件的设置
查看>>
TextKit简单示例
查看>>