1、重载二元操作符的方法

二元运算符又称为双目运算符,即需要2个操作数的运算符,例如 + - * / 等。

运算符重载可以分为3种方式:类的非静态成员函数、类的友元函数、普通函数。

例如有 2 个操作数 a 和 b,二元运算符 ? (表示一个二元运算符),a ? b 的操作会被解释为下面2种形式之一

  1. //a ? b
  2. a.operator?(b); //类的非静态成员函数
  3. operator(a, b); //友元函数 和 普通函数

第一种形式是运算符被重载为类的非静态成员函数,

这种方式要求运算符左边的的操作数(即第一个操作数a)必须是一个对象,operator?是这个对象的非静态成员函数

并且只能有一个参数。

第二种形式是运算符被重载为类的友元函数 或 普通函数,

这种方式需要2个参数,

重载为 类的友元函数 和 普通函数的区别是 类的友元函数可以直接访问类的私有成员,而普通函数不可以。

2、应用举例(对象 ? 对象)

下例中有3个complex类 ComplexA、ComplexB 和 ComplexC,3个类都重载了加减乘除 运算符。

其中ComplexA使用类的非静态成员函数方式重载,ComplexB使用类的友元函数方式重载,ComplexC使用普通函数方式重载。

需要注意的是复数的加减乘除运算的算法是有问题的,只是一个说明重载方法的例子,

另外重载函数的参数最好使用const关键字限定,至于返回值是否用const限定,需要取决于你的设计,比如允许C3 = ++(C1+C2)这种情况,就不能用cosnt限定。

至于不同类型的对象间的操作,通常是没有意义的。

  1. #include <iostream>
  2. using namespace std;
  3.  
  4. class ComplexA
  5. {
  6. public:
  7. //默认构造函数(Default constructor)
  8. ComplexA(){cout<<"Default Constructor"<<endl;}
  9. //带参数的构造函数(The constructor with parameters)
  10. ComplexA(double re, double im):real(re),image(im){cout<<"Parameter Constructor"<<endl;}
  11. //拷贝构造函数(Copy constructor)
  12. ComplexA(const ComplexA& ref){real = ref.real; image = ref.image; cout<<"Copy Constructor"<<endl;}
  13. //析构函数(destructor)
  14. ~ComplexA(){cout<<"Destructor"<<endl;}
  15.  
  16. //Operator Overload : +
  17. ComplexA operator+(ComplexA& ref)
  18. {
  19. return ComplexA(real + ref.real, image + ref.image);
  20. }
  21.  
  22. //Operator Overload : -
  23. ComplexA operator-(ComplexA& ref)
  24. {
  25. return ComplexA(real - ref.real, image - ref.image);
  26. }
  27.  
  28. //Operator Overload : *
  29. ComplexA operator*(ComplexA& ref)
  30. {
  31. return ComplexA(real * ref.real, image * ref.image);
  32. }
  33.  
  34. //Operator Overload : /
  35. ComplexA operator/(ComplexA& ref)
  36. {
  37. return ComplexA(real / ref.real, image / ref.image);
  38. }
  39.  
  40. //display
  41. void display(void){cout<<real<<"+"<<image<<"i"<<endl;}
  42. private:
  43. double real; //复数的实部
  44. double image; //复数的虚部
  45. };
  46.  
  47. class ComplexB
  48. {
  49. public:
  50. //默认构造函数(Default constructor)
  51. ComplexB(){cout<<"Default Constructor"<<endl;}
  52. //带参数的构造函数(The constructor with parameters)
  53. ComplexB(double re, double im):real(re),image(im){cout<<"Parameter Constructor"<<endl;}
  54. //拷贝构造函数(Copy constructor)
  55. ComplexB(const ComplexB& ref){real = ref.real; image = ref.image; cout<<"Copy Constructor"<<endl;}
  56. //析构函数(destructor)
  57. ~ComplexB(){cout<<"Destructor"<<endl;}
  58.  
  59. //Operator Overload : +
  60. friend ComplexB operator+(ComplexB& ref1, ComplexB& ref2)
  61. {
  62. return ComplexB(ref1.real + ref2.real, ref1.image + ref2.image);
  63. }
  64.  
  65. //Operator Overload : -
  66. friend ComplexB operator-(ComplexB& ref1, ComplexB& ref2)
  67. {
  68. return ComplexB(ref1.real - ref2.real, ref1.image - ref2.image);
  69. }
  70.  
  71. //Operator Overload : *
  72. friend ComplexB operator*(ComplexB& ref1, ComplexB& ref2)
  73. {
  74. return ComplexB(ref1.real * ref2.real, ref1.image * ref2.image);
  75. }
  76.  
  77. //Operator Overload : /
  78. friend ComplexB operator/(ComplexB& ref1, ComplexB& ref2)
  79. {
  80. return ComplexB(ref1.real / ref2.real, ref1.image / ref2.image);
  81. }
  82.  
  83. //display
  84. void display(void){cout<<real<<"+"<<image<<"i"<<endl;}
  85. private:
  86. double real; //复数的实部
  87. double image; //复数的虚部
  88. };
  89.  
  90. class ComplexC
  91. {
  92. public:
  93. //默认构造函数(Default constructor)
  94. ComplexC(){cout<<"Default Constructor"<<endl;}
  95. //带参数的构造函数(The constructor with parameters)
  96. ComplexC(double re, double im):real(re),image(im){cout<<"Parameter Constructor"<<endl;}
  97. //拷贝构造函数(Copy constructor)
  98. ComplexC(const ComplexC& ref){real = ref.real; image = ref.image; cout<<"Copy Constructor"<<endl;}
  99. //析构函数(destructor)
  100. ~ComplexC(){cout<<"Destructor"<<endl;}
  101.  
  102. //Get Data
  103. double GetReal(void){return real;}
  104. double GetImage(void){return image;}
  105.  
  106.   //display
  107. void display(void){cout<<real<<"+"<<image<<"i"<<endl;}
  108. private:
  109. double real; //复数的实部
  110. double image; //复数的虚部
  111. };
  112.  
  113. //Operator Overload : +
  114. ComplexC operator+(ComplexC& ref1, ComplexC& ref2)
  115. {
  116. return ComplexC(ref1.GetReal() + ref2.GetReal(), ref1.GetImage() + ref2.GetImage());
  117. }
  118.  
  119. //Operator Overload : -
  120. ComplexC operator-(ComplexC& ref1, ComplexC& ref2)
  121. {
  122. return ComplexC(ref1.GetReal() - ref2.GetReal(), ref1.GetImage() - ref2.GetImage());
  123. }
  124.  
  125. //Operator Overload : *
  126. ComplexC operator*(ComplexC& ref1, ComplexC& ref2)
  127. {
  128. return ComplexC(ref1.GetReal() * ref2.GetReal(), ref1.GetImage() * ref2.GetImage());
  129. }
  130.  
  131. //Operator Overload : /
  132. ComplexC operator/(ComplexC& ref1, ComplexC& ref2)
  133. {
  134. return ComplexC(ref1.GetReal() / ref2.GetReal(), ref1.GetImage() / ref2.GetImage());
  135. }
  136.  
  137. int main(void)
  138. {
  139. ComplexA C1(,), C2(, ), C3;
  140. C3 = C1 + C2; C3.display();
  141. C3 = C1 - C2; C3.display();
  142. C3 = C1 * C2; C3.display();
  143. C3 = C1 / C2; C3.display();
  144. cout <<"--------------------------------------"<<endl;
  145. ComplexB C4(,), C5(, ), C6;
  146. C6 = C4 + C5; C6.display();
  147. C6 = C4 - C5; C6.display();
  148. C6 = C4 * C5; C6.display();
  149. C6 = C4 / C5; C6.display();
  150. cout <<"--------------------------------------"<<endl;
  151. ComplexC C7(,), C8(, ), C9;
  152. C9 = C7 + C8; C9.display();
  153. C9 = C7 - C8; C9.display();
  154. C9 = C7 * C8; C9.display();
  155. C9 = C7 / C8; C9.display();
  156. return ;
  157. }

3、应用举例(对象 ? 基本数据类型 or 基本数据类型 ? 对象)

上面的例子中是对象 和 对象之间的运算符重载,如果需要一个是对象 + char/int/float/double,或者反过来 char/int/float/double + 对象,这时上面的程序的重载方式就不适用了。

需要定义新的重载,如下列程序所示。

  1. #include <iostream>
  2. using namespace std;
  3.  
  4. class ComplexD
  5. {
  6. public:
  7. ComplexD(double re = , double im = ):real(re),image(im){}
  8.  
  9. ComplexD operator+(ComplexD& ref){return ComplexD(real+ref.real, image+ref.image);};
  10. ComplexD operator+(int a){cout<<"IN\t int \t\t";return ComplexD(real+a, image);};
  11. ComplexD operator+(double d){cout<<"IN\t double \t";return ComplexD(real+d, image);};
  12. ComplexD operator+(float f){cout<<"IN\t float \t\t";return ComplexD(real+f, image);};
  13.  
  14. void display(void){cout<<real<<"+"<<image<<"i"<<endl;}
  15. double GetReal(void){return real;}
  16. double GetImage(void){return image;}
  17. private:
  18. double real;
  19. double image;
  20. };
  21.  
  22. ComplexD operator+(int a, ComplexD& ref){cout<<"OUT\t int \t\t";return ComplexD(ref.GetReal()+a, ref.GetImage());};
  23. ComplexD operator+(double d, ComplexD& ref){cout<<"OUT\t double \t";return ComplexD(ref.GetReal()+d, ref.GetImage());};
  24. ComplexD operator+(float f, ComplexD& ref){cout<<"OUT\t float \t\t";return ComplexD(ref.GetReal()+f, ref.GetImage());};
  25.  
  26. int main(void)
  27. {
  28. ComplexD D1(,), D2;
  29. D2 = D1 + ; D2.display();
  30. D2 = D1 + 2.1f; D2.display();
  31. D2 = D1 + 2.1; D2.display();
  32.  
  33. D2 = +D1; D2.display();
  34. D2 = 2.1f + D1; D2.display();
  35. D2 = 2.1 +D1; D2.display();
  36.  
  37. return ;
  38. }

C++运算符重载——重载二元运算符的更多相关文章

  1. C++ 重载运算符和重载函数

    C++ 重载运算符和重载函数 C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载. 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是 ...

  2. JavaScript一元运算符、二元运算符和三元运算符

    在JavaScript中,运算符可以根据其实际操作数的个数进行分类. JavaScript中的大多数运算符是一个二元运算符(binary operator),将两个表达式合并成为一个稍复杂的表达式.譬 ...

  3. C++ 运算符重载一(二元运算符重载)

    //二元运算符重载 #include<iostream> using namespace std; class Point { public: Point(int x,int y){ th ...

  4. C++之运算符重载(二元)

    一.加号+ 1.成员函数重载 2.友元函数重载 二.输出符号<< 三.索引符号 [ ] 四.补充说明 1.<二元运算符重载>课程评论: (一)为什么<<运算符的重载 ...

  5. [置顶] C++基础之六:运算符的重载

    网上太多有关运算符的重载了,但是写的太过的详细,不适合新手入门,特别是那什么++和--的前增量后增量重载,一元二元运算符重载,特殊运算符,下标运算符,new和delete,甚至是指针运算符的重载,吓退 ...

  6. C++解析七-重载运算符和重载函数

    重载运算符和重载函数C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载.重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列 ...

  7. C++ 自增、自减运算符的重载和性能分析

    01 ++.--运算符重载函数的格式 自增运算符和自减运算符是有前置和后置之分的,如: a++ // 后置自增运算符 ++a // 前置自增运算符 b-- // 后置自减运算符 --b // 前置自减 ...

  8. C++基础之自增和自减运算符的重载

    1. 格式 1.1 分为前置和后置格式: int x = 0; int y = 0; // 后置自增运算符 x++; // 前置自增运算符 ++x; // 后置自减运算符 y--; // 前置自减运算 ...

  9. C++ Primer : : 第十四章 : 重载运算符与类型转换之类型转换运算符和重载匹配

    类型转换运算符 class SmallInt { public: SmallInt(int i = 0) : val(i) { if (i < 0 || i > 255) throw st ...

随机推荐

  1. django概述

    一.django的特点 1.提供一体化的web解决方案,什么叫一体化:mvc 2.等你玩儿牛逼了可以拔插组件,换成自己顺手或者更牛逼的组件

  2. trap命令使用

    分享一个shell脚本技巧,大家写shell脚本的时候,一般而言仅仅保证功能可用,但程序的鲁棒性却不是太好,不够健壮,多数是脚本处理 一些中断信号导致,应对非预期的系统信号,其实系统自带的trap命令 ...

  3. 关于使用regsvr32命令注册ActiveX控件失败的解决办法

    昨天小编也遇到这样问题,步骤一切都对,没有错误,但是每次在命令行下输入的时候,都会弹出一个对话框: 最后我发现是存放ActiveX控件的路径中带有中文文件名字所导致,所以导致的错误,我们将所在路径下的 ...

  4. Factorial Trailing Zeroes

    Given an integer n, return the number of trailing zeroes in n!. Note: Your solution should be in log ...

  5. java笔试题(2)

    简述构造器的运行机制 首先要注意的是的构造器并不是函数,所以他并不能被继承,这在我们extends的时候写子类的构造器时比较的常见,即使子类构造器参数和父类的完全一样,我们也要写super就是因为这个 ...

  6. kibana 修改Ico图标

    修改此路径下的E:\happy\kinbana\kibana-4.2.2-windows\kibana-4.2.2-windows\optimize\bundles的commons.bundle.js ...

  7. 【Merge Sorted Array】cpp

    题目: Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. Not ...

  8. CSS3动画制作的简单示例

    CSS3 大大强化了制作动画的能力,但是如果要做出图案比较复杂的动画,选择 GIF 依然是一个不错的选择.今天给大家介绍一个使用 CSS animation 配合雪碧图(CSS sprite)来制作动 ...

  9. Bootstrap的宽度和分辨率的差别

    首先在bootstrap里面所有的样式并在pc上是根据px的单位来判断的,就是我们说的分辨率, @media(min-width:1200px){ ......里面的样式 } 那么就是说当你的屏幕放大 ...

  10. NYOJ-85 有趣的数 AC 分类: NYOJ 2014-01-17 21:42 240人阅读 评论(0) 收藏

    这道题目就是,找规律,小学奥数,找规律不难吧, #include<stdio.h> int sc(int x); int main(){ int n=0; int num,cs,k; sc ...