8.9.1 在数值类中重载运算符(2)
该类中新的函数声明给出两个重载的*运算符函数,两者分别使double类型数值在前面和在后面与Length对象相乘。类外部对应于数值在前乘法的operator*()函数的定义如下所示:
- Length Length::operator *(double x, Length len)
- {
- int ins = safe_cast<int>(x*len.inches +x*len.feet*inchesPerFoot);
- return Length(ins/12, ins %12);
- }
数值在后的乘法运算符版本现在可以根据上面的函数实现:
- Length Length::operator *(Length len, double x)
- { return operator*(x, len); }
该函数仅仅颠倒了一下实参,然后调用数值在前的乘法运算符版本。我们可以用下面的代码段来练习这两个函数的用法:
- double factor = 2.5;
- Console::WriteLine(L"{0} times {1} is {2}",
factor, len2, factor*len2); - Console::WriteLine(L"{1} times {0} is {2}",
factor, len2, len2*factor);
该代码段的两行输出应该反映出相同的乘法结果(19英尺2英寸)。实参表达式factor*len2等价于:
- Length::operator*(factor, len2).ToString()
调用静态operator*()函数将得到新的Length对象,而调用该对象的ToString()函数将产生WriteLine()函数的实参。表达式len2*factor与此类似,但调用的是形参颠倒的operator*()函数。虽然operator*()函数是为处理double类型的乘数而编写的,但它们同样可以处理整数。当我们在诸如12*(len1+len2)之类的表达式中使用*运算符时,编译器将自动把整数值升级为double类型。
在可运行的示例中,我们可以对Length类的重载运算符稍微作一些扩充。
试一试:包含重载运算符的数值类
本示例为Length类实现了加法、乘法和除法的运算符重载:
- // Ex8_12.cpp : main project file.
- // Overloading operators in the value class, Length
- #include "stdafx.h"
- using namespace System;
-
- value class Length
- {
- private:
- int feet;
- int inches;
-
- public:
- static initonly int inchesPerFoot = 12;
-
- // Constructor
- Length(int ft, int ins) : feet(ft), inches(ins){ }
-
- // A length as a string
- virtual String^ ToString() override
- { return feet+L" feet " + inches + L" inches"; }
-
- // Addition operator
- Length operator+(Length len)
- {
- int inchTotal = inches+len.inches+inchesPerFoot*(feet+len.feet);
- return Length(inchTotal/inchesPerFoot, inchTotal%inchesPerFoot);
- }
-
- // Division operator
- static Length operator/(Length len, double x)
- {
- int ins = safe_cast<int>((len.feet*inchesPerFoot + len.inches)/x);
- return Length(ins/inchesPerFoot, ins%inchesPerFoot);
- }
-
- static Length operator*(double x, Length len);
- //
Pre-multiply by a double value - static Length operator*(Length len, double x);
- //
Post-multiply by a double value - };
-
- Length Length::operator *(double x, Length len)
- {
- int ins = safe_cast<int>(x*len.inches +x*len.feet*inchesPerFoot);
- return Length(ins/inchesPerFoot, ins%inchesPerFoot);
- }
-
- Length Length::operator *(Length len, double x)
- { return operator*(x, len); }
-
- int main(array<System::String ^> ^args)
- {
- Length len1 = Length(6, 9);
- Length len2 = Length(7, 8);
- double factor = 2.5;
-
- Console::WriteLine(L"{0} plus {1} is {2}", len1, len2, len1+len2);
- Console::WriteLine(L"{0} times {1} is {2}", factor, len2, factor*len2);
- Console::WriteLine(L"{1} times {0} is {2}", factor, len2, len2*factor);
- Console::WriteLine(L"The sum of {0} and {1} divided by {2} is {3}",
- len1, len2, factor, (len1+len2)/factor);
-
- return 0;
- }