类型 类名::operator 运算符(参数){} |
class Complex { public: int a; int b; public: Complex(int a = 0, int b = 0) { this->a = a; this->b = b; } void printCom() { cout<<a<<"+"<<b<<"i"<<endl; } }; void main01() { Complex c1(1, 2), c2(3, 4);
int a = 10, b = 20; a = a + b; //int 是基础类型,编译器已经为这些类型提供+操作了。 //c1 = c1 + c2; //c1的类型是 Complex,这种类型,是自定义类型。 编译器根本不知道如何加, //但是c++编译器会给你提供一个机制,让你实现自定义类型加 system("pause"); } //1操作符重载,首先是通过函数实现的。 Complex ComAdd(Complex &c1, Complex &c2) //实现两对象相加,推演1 { Complex tmp; tmp.a = c1.a + c2.a; tmp.b = c1.b + c2.b; return tmp; } Complex operator+(Complex &c1, Complex &c2) //实现两对象相加,推演2(改变函数名) { Complex tmp; tmp.a = c1.a + c2.a; tmp.b = c1.b + c2.b; return tmp; } void main() { Complex c1(1, 2), c2(3, 4); //Complex c3 = ComAdd(c1, c2); //使用操作推演1 //Complex c3 = operator+(c1, c2); //使用操作推演2 Complex c3 = c1 + c2; //使用操作推演3
c3.printCom(); system("pause"); } |
操作符重载的两种方法 |
1, 全局友元函数配合使用 class Complex { private: int a; int b; //通过友元函数实现+操作,目的是方便使用私有数据 friend Complex operator+(Complex &c1, Complex &c2); public: Complex(int a = 0, int b = 0) { this->a = a; this->b = b; } void printCom() { cout<<a<<"+"<<b<<"i"<<endl; } }; //全局函数实现运算符重载 Complex operator+(Complex &c1, Complex &c2) { Complex tmp; tmp.a = c1.a + c2.a; tmp.b = c1.b + c2.b; return tmp; } 解释为operator op(ObjL,ObjR)左右操作数都由参数传递 2,通过通过类的成员函数实现运算符重载 public: //通过类的成员函数实现-操作 Complex operator-(Complex &c2) { Complex tmp; tmp.a = this->a -c2.a; tmp.b = b -c2.b; return tmp; } 解释为 objL.operator op(objR) 左操作数objL通过this传递,右操作符由objR传递 |
单操作数操作符重载 |
前置++ Complex& operator++(Complex &c2); 实现: Complex& operator++(Complex &c2) //一般返回引用 { c2.a++; c2.b++; return c2; } 后置++ Complex operator++(Complex &c2,int);//加一个int占位符 实现: Complex operator++(Complex &c2,int) //一般返回对象 { Complex tmp; Tmp = c2; tmp.a ++; tmp.b++; return tmp; } |
运算符重载使用友元全局函数还是成员函数的时机 |
全局函数如果左操作数为系统类,如果变为成员函数就要写在系统类里通过系统类.operator op()来调用,也就是要重载运算符就要改变系统类中该成员方法的实现,显然这是不行的,因此这种情况只能用友元全局函数。其余情况最好用成员函数 |
ostream& operator<<(ostream &out, Complex &c1) { cout<<"12345,上山打老虎"<<endl; cout<<c1.a<<"+"<<c1.b<<"i"<<endl; return out; //将引用接收进来,又返回出去,实现链式编程 } //函数返回值当左值的时候,需要返回一个对象的引用 cout<<c1 <<"aaa"; //当cout<<c1 之后又返回一个cout对象,将”aaa”左移至cout |
实例:复数类 #include "iostream" using namespace std; class Complex { private: int a; int b; friend ostream& operator<<(ostream &out, Complex &c1); public: Complex(int a = 0, int b = 0) { this->a = a; this->b = b; } void printCom() { cout<<a<<"+"<<b<<"i"<<endl; } public: //通过类的成员函数实现-操作 Complex operator-(Complex &c2) { Complex tmp; tmp.a = this->a -c2.a; tmp.b = b -c2.b; return tmp; } Complex operator+(Complex &c2) { Complex tmp; tmp.a = this->a + c2.a; tmp.b = b + c2.b; return tmp; } // 前置-- Complex& operator--() { this->a--; this->b--; return *this; } // 前置++ Complex& operator++() { this->a++; this->b++; return *this; } //后置-- Complex operator--(int) { Complex tmp = *this; this->a --; this->b --; return tmp; } //后置++ Complex operator++(int) { Complex tmp = *this; this->a ++; this->b ++; return tmp; } }; //1操作符重载,首先是通过函数实现的。 void main61() { Complex c1(1, 2), c2(3, 4); //Complex c3 = ComAdd(c1, c2); //Complex c3 = operator+(c1, c2); //2 +操作符有两个参数 左操作数 和 右操作数 //3 Complex c3 = c1 + c2; c3.printCom(); Complex c4 = c1.operator-(c2); c4.printCom(); Complex c5 = c1 - c2 ; c5.printCom(); //目标 通过类的成员函数,完成操作符重载 //1 要承认操作符重载是一个函数,要写函数原型 //2 写出函数调用语言 c1.operator-(c2) //3 完善函数原型 ++c2; c2.printCom(); //全局函数原型推导 //Complex& operator++(Complex &c2); --c2; //c2.operator--(); c2.printCom(); //测试全局函数实现后置++ c2++; c2.printCom(); //测试用类成员函数实现后置-- c2--; c2.printCom(); system("pause"); } ostream& operator<<(ostream &out, Complex &c1) { cout<<"12345,上山打老虎"<<endl; cout<<c1.a<<"+"<<c1.b<<"i"<<endl; return out; } //1操作符重载,首先是通过函数实现的。 void main() { Complex c1(1, 2), c2(3, 4); int a = 10; char *p = "abc"; cout<<a<<endl; cout<<p<<endl; cout<<c1<<"链式编程测试"<<endl; operator<<(cout, c1); //函数返回值当左值的时候,需要返回一个对象的引用 //cout<<c1 <<"aaa"; //没有方法去在cout类里面添加函数operator<<,只能通过全局函数实现。 //cout.operator<<( c1); //void operator<<(ostream &out, Complex &c1) system("pause"); } |
运算符重载之[ ] , == , = , != 重载 |
运算符重载
最新推荐文章于 2021-09-27 18:07:00 发布
