//第八章深入理解类 //8.9 C++/CLI编程 /* C++/CLI类支持运算符的重载,但它和本地C++类有一些区另应该掌握,首先是C++/CLI类与本地C++类中运算符重载之间的基本区别 有两个区别前面已经介绍过了 决不能在数值类中重载赋值运算符,因为将数值类对像赋值给另一个同类对像的过程已经被定义为一个成员一个成员的进行复制 这一点不能改变,前面还提到,与本地类不同,引用类没有默认的赋值运算符 如果我们需要以赋值运算符来处理引用类对像,则需要实现适当的函数 另一个与本地C++类的区别是,C++/CLI类中实现的运算符重载的函数可以是类的静态成员,也可以是实例成员 这意味着除了在本地C++的下下文中看到的运算符函数可以是带一个形参的实例函数或带两个形参的非成员函数这两种可能性以外,我们在C++/CLI为右还可以选择以带两个形参的静态成员函数的形式实现二元运算符 同样,在C++/CLI中可以将前缀一运算符实现为不带形参的静态成员函数,最后,虽然本地C++允许重载new运算符 但是C++/CLI类中我们却不能重载gcnew运算符 */ //8.9.1 在数值类中重载运算符 //没看过书哦,少写了一章,value就是定久数值类的一个关键字吗? #include "stdafx.h" #include <iostream> #include <string> using namespace std; using namespace System; /*value class Length { private: int feet; int inches; public: static initonly int inchesPerFoot = 12; //initonly意味着该常量不能被修改, Length(int ft, int ins):feet(ft), inches(ins) { } virtual String^ ToString() override { return feet+L" feet "+inches+" inches "; } //重载运算符operator+ Length operator+(Length len) { int inchTotal = inches + len.inches + inchesPerFoot * (feet+len.feet); //重新构造对像返回 return Length(inchTotal/inchesPerFoot, inchTotal%inchesPerFoot); } //将operator+()函数定义成Length类的静态成员 static Length operator+(Length len1, Length len2) { //int inchTotal = inches + len.inches + inchesPerFoot * (feet+len.feet); int inchTotal = len1.inches + len2.inches + inchesPerFoot * (len1.feet+len2.feet); //重新构造对像返回 return Length(inchTotal/inchesPerFoot, inchTotal%inchesPerFoot); } };*/ /* value class Length { private: int feet; int inches; public: static initonly int inchesPerFoot = 12; //initonly意味着该常量不能被修改, Length(int ft, int ins):feet(ft), inches(ins) { } virtual String^ ToString() override { return feet+L" feet "+inches+" inches "; } //重载运算符operator+ Length operator+(Length len) { int inchTotal = inches + len.inches + inchesPerFoot * (feet+len.feet); //重新构造对像返回 return Length(inchTotal/inchesPerFoot, inchTotal%inchesPerFoot); } static Length operator*(double x, Length len); static Length operator*(Length len, double x); }; int main(array<System::String ^> ^args) { Length len1 = Length(6, 9); Length len2 = Length(7, 8); Console::WriteLine(L"{0} plus {1} is {2}",len1, len2, len1+len2); double factor = 2.5; Console::WriteLine(L"{0} times {1} is {2}", factor, len2, factor*len2); Console::WriteLine(L"{0} times {1} is {2}", factor, len2, len2*factor); system("pause"); return 0; } 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); //颠倒一下实参,然后调用数值在前的乘法运算符版本 }*/ //包含重载运算符的数值类 /*#include "stdafx.h" #include <iostream> #include <string> using namespace std; using namespace System; value class Length { private: int feet; int inches; public: static initonly int inchesPerFoot = 12; Length(int ft, int ins):feet(ft), inches(ins) { } virtual String^ ToString() override { return feet+" feet "+inches+" inches "; } Length operator+(Length len) { int inchTotal = inches + len.inches + inchesPerFoot *(feet*len.feet); return Length(inchTotal/inchesPerFoot, inchTotal%inchesPerFoot); } 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%(Length len1, Length len2) { int ins =(len1.feet * inchesPerFoot + len1.inches) % (len1.feet*inchesPerFoot + len2.inches); return Length(ins/inchesPerFoot, ins%inchesPerFoot); } static Length operator*(double x, Length len); static Length operator*(Length len, double x); }; Length Length::operator*(double x, Length len) { int inchs = safe_cast<int>(x*len.inches + x*len.feet * inchesPerFoot); return Length(inchs/inchesPerFoot, inchs%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} + {1} = {2}", Len1, Len2, Len1+Len2); Console::WriteLine(L"{0} * {1} = {2}", factor, Len1, factor*Len2); Console::WriteLine(L"{0} * {1} = {2}", Len1, factor, factor*Len2); Console::WriteLine(L"({0} + {1}) / {2} = {3}", Len1, Len2, factor, (Len1+Len2)/factor); system("pause"); return 0; }*/ //8.9.2 重载递增和递减运算符 /*#include "stdafx.h" #include <iostream> #include <string> using namespace std; using namespace System; value class Length { private: int feet; int inches; public: static initonly int inchesPerFoot = 12; Length(int ft, int ins):feet(ft), inches(ins) { } virtual String^ ToString() override { return feet+" feet "+inches+" inches "; } Length operator+(Length len) { int inchTotal = inches + len.inches + inchesPerFoot *(feet*len.feet); return Length(inchTotal/inchesPerFoot, inchTotal%inchesPerFoot); } 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%(Length len1, Length len2) { int ins =(len1.feet * inchesPerFoot + len1.inches) % (len1.feet*inchesPerFoot + len2.inches); return Length(ins/inchesPerFoot, ins%inchesPerFoot); } static Length operator++(Length len) { ++len.inches; len.feet += len.inches/len.inchesPerFoot; len.inches %= len.inchesPerFoot; return len; } //前缀和后缀递增操作使用的应该是Length类中同一个运算符函数,因此输出证实两者都能正确工作 //是因为编译器能够确定是在递增操作数之前,还是在递增操作数之后在周围的静达式中使用该操作数的值 static Length operator*(double x, Length len); static Length operator*(Length len, double x); }; Length Length::operator*(double x, Length len) { int inchs = safe_cast<int>(x*len.inches + x*len.feet * inchesPerFoot); return Length(inchs/inchesPerFoot, inchs%inchesPerFoot); } Length Length::operator*(Length len, double x) { return operator*(x, len); } int main(array<System::String ^> ^args) { Length Len1 = Length(1, 11); Console::WriteLine(Len1++); Console::WriteLine(++Len1); system("pause"); return 0; }*/ //8.9.3 在引用类中重载运算符 #include "stdafx.h" #include <iostream> #include <string> using namespace std; using namespace System; ref class Length { private: int feet; int inches; public: static initonly int inchesPerFoot = 12; Length(int ft, int ins) : feet(ft), inches(ins){ } virtual String^ ToString() override { return feet+L" feet " + inches + L" inches"; } Length^ operator+(Length^ len) { int inchTotal = inches + len->inches + inchesPerFoot *(feet+len->feet); return gcnew Length(inchTotal/inchesPerFoot, inchTotal%inchesPerFoot); } static Length^ operator/(Length^ len, double x) { int ins = safe_cast<int>((len->feet*inchesPerFoot + len->inches)/x); return gcnew Length(ins/inchesPerFoot, ins%inchesPerFoot); } static int operator/(Length^ len1, Length^ len2) { return (len1->feet*inchesPerFoot + len1->inches)/(len2->feet*inchesPerFoot + len2->inches); } static Length^ operator%(Length^ len1, Length^ len2) { int ins =(len1->feet * inchesPerFoot + len1->inches) % (len2->feet*inchesPerFoot + len2->inches); return gcnew Length(ins/inchesPerFoot, ins%inchesPerFoot); } static Length^ operator++(Length^ len) { Length^ temp = gcnew Length(len->feet, len->inches); ++temp->inches; temp->feet += temp->inches/temp->inchesPerFoot; temp->inches %= temp->inchesPerFoot; return temp; } //前缀和后缀递增操作使用的应该是Length类中同一个运算符函数,因此输出证实两者都能正确工作 //是因为编译器能够确定是在递增操作数之前,还是在递增操作数之后在周围的静达式中使用该操作数的值 static Length^ operator*(double x, Length^ len); static Length^ operator*(Length^ len, double x); }; Length^ Length::operator*(double x, Length^ len) { int ins = safe_cast<int>(x*len->inches +x*len->feet*inchesPerFoot); return gcnew Length(ins/inchesPerFoot, ins%inchesPerFoot); } Length^ Length::operator*(Length^ len, double x) { return operator*(x, len); } int main(array<System::String ^> ^args) { //Length^ Len1 = gcnew Length(2, 6); //Length^ Len2 = gcnew Length(3, 5); //Length^ Len3 = gcnew Length(14, 6); Length^ Len1 = gcnew Length(2,6); // 2 feet 6 inches Length^ Len2 = gcnew Length(3,5); // 3 feet 5 inches Length^ Len3 = gcnew Length(14,6); // 14 feet 6 inches //Length^ total = 12 * (Len1 + Len2 + Len3) + (Len3 /gcnew Length(1,7))*Len2; Length^ total = 12*(Len1+Len2+Len3) + (Len3/gcnew Length(1,7))*Len2; Console::WriteLine(total); //Console::WriteLine(L"{0} can be cut into {1} pieces {2} long with {3} left over.", // Len3, Len3/Len1, Len1, Len3 %Len1); Length^ len5 = gcnew Length(1, 11); Console::WriteLine(len5++); Console::WriteLine(++len5); Console::WriteLine(len5); system("pause"); return 0; } //8.9.4 实现引用类型的赋值运算符 Length% operator=(const Length% len) { if(this != %len){ feet = len.feet; inches = len.inches; } return *this; }