C++ 一些学习笔记(十)类和对象-运算符重载

    科技2022-07-10  162

    C++ 一些学习笔记(十)类和对象-运算符重载

    主要是针对之前学习C的时候一些知识点的遗漏的补充,还有一些我自己觉得比较重要的地方。本文章的主要内容是关于运算符重载。1.加号运算符重载2.左移运算符重载3.递增运算符重载4.赋值运算符重载5.关系运算符重载6.函数调用运算符重载

    主要是针对之前学习C的时候一些知识点的遗漏的补充,还有一些我自己觉得比较重要的地方。

    本文章的主要内容是关于运算符重载。

    运算符重载:对已有的运算符进行定义,赋予其另一种功能,以适应不同的数据类型。

    1.加号运算符重载

    作用:实现两个自定义数据类型相加的运算 通过自己写成员函数,实现两个对象相加属性后返回新的对象。

    1.成员函数重载+ 2.全局函数重载+ class Person{ public: ///Person operator+(Person &p){/1.成员函数重载+ ///Person temp; ///temp.m_A=this->m_A+p.m_A; ///temp.m_B=this->m_B+p.m_B; ///return temp; ///} int m_A; int m_B; }; Person operator+(Person &p1,Person &p2){/2.全局函数重载+ Person temp; temp.m_A=p1.m_A+p2.m_A; temp.m_B=p1.m_B+p2.m_B; return temp; } Person operator+(Person &p1,int num){///函数重载的版本 Person temp; temp.m_A=p1.m_A+p2.num; temp.m_B=p1.m_B+p2.num; return temp; } void test01(){ Person p1; p1.m_A=10; p1.m_B=10; Person p2; p2.m_A=10; p2.m_B=10; 成员函数重载+的本质调用 //Person p3=p1.operator+(p2); 全局函数重载+的本质调用 //Person p3=operator+(p1,p2); 两个对象相加 Person p3=p1+p2;//上述两种本质调用都可以简化成这种形式 Person p4=p1+10;//运算符重载也可以发生函数重载 Person+int cout<<"p3.m_A="<<p3.m_A<<endl; cout<<"p3.m_B="<<p3.m_B<<endl; cout<<"p4.m_A="<<p4.m_A<<endl; cout<<"p4.m_B="<<p4.m_B<<endl; }

    2.左移运算符重载

    作用:可以输出自定义数据类型

    class Person{ friend ostream & operator<<(ostream &cout,Person &p); public: Person(int a,int b){ m_A=a; m_B=b; } private: //不会利用成员函数重载左移运算符,因为无法实现cout在左侧 //利用成员函数左移运算符 p.operator<<(cout) 简化版本 p<<cout //void orerator<<(cout){ //} Person(int a,int b){ this->m_A=a; this->m_B=b; } }; void test01(){ Person p(10,10); cout<<p<<endl; } //只能利用全局函数重载左移运算符 ostream & operator<<(ostream &cout,Person &p){//本质 operator<<(cout,p) 简化 cout<<p cout<<"m_A="<<p.m_A<<"m_B="; return cout; } int main(){ test01(); } 重载左移运算符配合友元可以实现输出自定义数据类型

    3.递增运算符重载

    作用:通过重载递增运算符,实现自己的整形数据

    class MyIneger{ friend ostrsam & operator<<(ostream&cout,MyInteger myint); public: MyInteger(){ m_Num=0; } 重载前置++运算符 MyInteger& operator++(){ m_Num++;//先进行++ return *this;//再返回自身 } 重载后置++运算符 MyInteger operator++(int){//int代表占位参数,可以用于区分前置和后置递增 MyInteger temp=*this; m_Num++return temp; } private: int m_Num; }; ostrsam & operator<<(ostream&cout,MyInteger myint){ cout<<myint.m_Num; return cout; } void test01(){ MyInteger myint; cout<<++myint<<endl; } void test01(){ MyInteger myint; cout<<myint++<<endl; } int main(){ test01(); } 前置递增返回引用,后置递增返回值

    4.赋值运算符重载

    C++编译器至少给一个类添加四个函数 1.默认构造函数 2.默认析构函数 3.默认拷贝构造函数 4.赋值运算符operator=对属性进行值拷贝

    如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题

    class Person{ public: Person(int age){ m_Age=new int(age); } ~Person(){ if(m_Age!=NULL){ delete m_Age; m_Age=NULL; } } 重载赋值运算符 Person& operator=(Person&p){ //编译器提供的是浅拷贝 //m_A=p.m_Age; 应该先判断是否有属性在堆区,如果有先释放干净,再进行深拷贝 if(m_Age!=NULL){ delete m_Age; m_Age=NULL: } m_Age=new int(*p.m_Age);//深拷贝 return *this;//返回对象本身 } int *m_Age; }; void01(){ Person p1(18); Person p2(20); Person p3(30); p3=p2=p1; cout<<"p1的年龄为:"<<*p1.m_Age<<endl; cout<<"p2的年龄为:"<<*p2.m_Age<<endl; cout<<"p3的年龄为:"<<*p3.m_Age<<endl; } int main(){ int a=10; int b=20; int c=30; test01(); }

    5.关系运算符重载

    作用:重载关系运算符,可以让两个自定义类型对象进行对比操作

    class Person{ public: Person(string name,int age){ this->m_Name=name; this->m_Age=age; }; bool operator==(Person&p){ if(this->m_Name==p.m_Name&&this->m_Age==p.m_Age){return true;} else return false; } bool operator!=(Person&p){ if(this->m_Name=p.m_Name&&this->m_Age==p.m_Age){return false;} else return true; } string m_Name; int m_Age; }; void test01(){ Person p1("Tom",18); Person p2("Tom",18); if(p1==p2){cout<<"p1和p2是相等的"<<endl;} else{cout<<"p1和p2是不相等的"<<endl;} if(p1!=p2){cout<<"p1和p2是不相等的"<<endl;} else{cout<<"p1和p2是相等的"<<endl;} } int main(){ }

    6.函数调用运算符重载

    函数调用运算符()也可以重载由于重载后的使用方式非常像函数的调用,因此称为仿函数仿函数没有固定写法,非常灵活 class MyPrint{ public: 重载函数调用运算符 void operator()(string test){ cout<<test<<endl; } }; void test01(){ MyPrint myPrint; myPring("hello world");//由于重载后的使用方式非常像函数的调用,因此称为仿函数 } class MyAdd{ public: int operate()(int num1,int num2){ return num1+num2; } } void test02(){ MyAdd myadd; int ret=myadd(100,100); cout<<"ret="<<endl; } int main(){ test01(); test02(); }
    Processed: 0.044, SQL: 8