设为首页 加入收藏

TOP

8.9.3 在引用类中重载运算符
2013-10-07 12:36:14 来源: 作者: 【 】 浏览:66
Tags:8.9.3 引用 重载 运算

8.9.3  在引用类中重载运算符

在引用类中重载运算符基本上与在数值类中重载运算符相同,主要区别在于形参和返回值通常都是句柄。下面介绍作为引用类实现的Length类,然后可以对两个版本作一番比较。

试一试:在引用类中重载运算符

该示例将Length定义成引用类,其中包括一组与数值类版本相同的重载运算符:

  1. // Ex8_13.cpp : main project file.  
  2. // Defining and using overloaded operator  
  3.  
  4. #include "stdafx.h"  
  5. using namespace System;  
  6.  
  7. ref class Length  
  8. {  
  9. private:  
  10. int feet;  
  11. int inches;  
  12.  
  13. public:  
  14. static initonly int inchesPerFoot = 12;  
  15.  
  16. // Constructor  
  17. Length(int ft, int ins) : feet(ft), inches(ins){ }  
  18.  
  19. // A length as a string  
  20. virtual String^ ToString() override  
  21. { return feet+L" feet " + inches + L" inches"; }  
  22.  
  23. // Overloaded addition operator  
  24. Length^ operator+(Length^ len)  
  25. {  
  26. int inchTotal = inches+len->inches+inchesPerFoot*(feet+len->feet);  
  27. return gcnew Length(inchTotal/inchesPerFoot, 
    inchTotal%inchesPerFoot);  
  28. }  
  29.  
  30. // Overloaded divide operator - right operand type double  
  31. static Length^ operator/(Length^ len, double x)  
  32. {  
  33. int ins = safe_cast<int>((len->feet*inchesPerFoot + len->inches)/x);  
  34. return gcnew Length(ins/inchesPerFoot, ins%inchesPerFoot);  
  35. }  
  36.  
  37. // Overloaded divide operator - both operands type Length  
  38. static int operator/(Length^ len1, Length^ len2)  
  39. {  
  40. return (len1->feet*inchesPerFoot + len1->inches)/  
  41.                              (len2->feet*
    inchesPerFoot + len2-
    >inches);  
  42. }  
  43.  
  44. // Overloaded remainder operator  
  45. static Length^ operator%(Length^ len1, Length^ len2)  
  46. {  
  47. int ins = (len1->feet*inchesPerFoot + len1->inches)%  
  48.                                (len2->feet*inches
    PerFoot + len2-
    >inches);  
  49. return gcnew Length(ins/inchesPerFoot, ins%inchesPerFoot);  
  50. }  
  51.  
  52. static Length^ operator*(double x, Length^ len);  
  53.                                         // 
    Multiply - L operand double  
  54. static Length^ operator*(Length^ len, double x);  
  55.                                         // 
    Multiply - R operand double  
  56.  
  57. // Pre- and postfix increment operator  
  58. static Length^ operator++(Length^ len)  
  59. {  
  60. Length^ temp = gcnew Length(len->feet, len->inches);  
  61. ++temp->inches;  
  62. temp->feet += temp->inches/temp->inchesPerFoot;  
  63. temp->inches %= temp->inchesPerFoot;  
  64. return temp;  
  65. }  
  66. };  
  67.  
  68. // Multiply operator implementation - left operand double  
  69. Length^ Length::operator*(double x, Length^ len)  
  70. {  
  71. int ins = safe_cast<int>(x*len->inches +x*len->feet*inchesPerFoot);  
  72. return gcnew Length(ins/inchesPerFoot, ins%inchesPerFoot);  
  73. }  
  74.  
  75. // Multiply operator implementation - right operand double  
  76. Length^ Length::operator*(Length^ len, double x)  
  77. { return operator*(x, len); }  
  78.  
  79. int main(array<System::String ^> ^args)  
  80. {  
  81. Length^ len1 = gcnew Length(2,6); // 2 feet 6 inches  
  82. Length^ len2 = gcnew Length(3,5); // 3 feet 5 inches  
  83. Length^ len3 = gcnew Length(14,6); // 14 feet 6 inches  
  84.  
  85. // Use +, * and / operators  
  86. Length^ total = 12*(len1+len2+len3) + (len3/gcnew Length(1,7))*len2;  
  87. Console::WriteLine(total);  
  88.  
  89. // Use remainder operator  
  90. Console::WriteLine(  
  91. L"{0} can be cut into {1} pieces {2} long with {3} left over.",  
  92. len3, len3/len1, len1, len3%len1);  
  93. Length^ len4 = gcnew Length(1, 11); // 1 foot 11 inches  
  94.  
  95. // Use pre- and postfix increment operator  
  96.  
  97. Console::WriteLine(len4++); // Use postfix increment operator  
  98. Console::WriteLine(++len4); // Use prefix increment operator  
  99. Console::WriteLine(len4); // Final value of len4  
  100. return 0;  

该示例产生下面的输出:

  1. 275 feet 9 inches  
  2. 14 feet 6 inches can be cut into 5 pieces 2 feet 6 inches long  
  3. with 2 feet 0 inches left over.  
  4. 1 feet 0 inches  
  5. 2 feet 0 inches  
  6. 2 feet 1 inches 

示例说明

与数值类相比,主要区别在于重载运算符函数的形参和返回类型,因此本例使用->运算符,另外Length类型的对象现在是使用gcnew关键字在CLR堆上创建的。此外,重载的递增运算符函数返回一个临时对象,并且没有用引用实参修改原始对象。

重要的是当我们在引用类中重载递增或递减运算符时没有修改原始对象,因为编译器生成的代码依赖于传递给重载函数的对象,原始代码没有修改。当为某个后缀递增或递减运算调用该函数时,用出现它的表达式中的对象生成代码,然后存储返回的对象来替换原始对象。尽管有这些变化,代码仍基本上相同,该运算符函数与上一个示例中一样有效。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇8.9.1 在数值类中重载运算符(1) 下一篇8.9.4 实现引用类型的赋值运算符

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: