我是
靠谱客的博主
俊逸学姐,最近开发中收集的这篇文章主要介绍
c++ base-操作符重载,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
操作符重载包括两种形式类成员函数实现操作符重载和友元函数实现操作符重载
之所以是这两种,是因为只有类的成员函数和友元函数才能访问类的私有变量,而显然操作符重载时,需要操作类的成员数据,如果成员数据是私有的,那么要么重载方法是类的成员函数,要么是类的友元函数,要么专门写一堆操作成员函数来实现(非成员函数非友元函数的重载操作符函数)来访问类的私有变量。
a.类成员函数实现操作符重载
- class 类名
- {
- public:
- 返回类型 operator 操作符(形参表);
- };
-
- 返回类型 类名::operator 操作符(形参表)
- {
-
- }
关系运算符由类的成员函数重载
- #include<iostream>
- #include<string>
- using namespace std;
- class Sale_item
- {
- int bookid;
- int price;
- public:
- Sale_item operator +(Sale_item a);
- void SetItem(int a,int b);
- };
- Sale_item Sale_item::operator +(Sale_item a)
- {
- int temp=-1;
- if(a.bookid==this->bookid)
- temp=a.price+this->price;
- Sale_item s;
- s.bookid=a.bookid;
- s.price=temp;
- return s;
-
- }
- void Sale_item::SetItem(int a,int b)
- {
- bookid=a;
- price=b;
- }
- int main()
- {
- Sale_item s1,s2;
- s1.SetItem(1,1);
- s2.SetItem(1,2);
- s1=s1+s2;
- }
使用类成员函数进行操作符重载时只需要一个形参,因为除了这个形参成员函数
还有一个隐含的形参this,this形参限定为第一个操作数
,所以+虽然是2数操作,在使用类成员函数重载时,只需要一个参数就行。
另外需要注意的是用this访问类成员是this->而不是this.
赋值(=),下标([ ]),调用(()),成员访问(->)的重载必须是用成员函数来重载,不然会发生编译错误
一般一元操作符返回的是引用&,二元操作符返回的是对象(如果二元操作也返回引用,那么应该返回谁的引用呢?)
赋值运算符的重载(写成友元会报错Sale_item& operator=(....)must be a non-static member!)
赋值运算必须返回对*this 的引用(c++Primer)
- #include<iostream>
- #include<string>
- using namespace std;
- class Sale_item
- {
- private:
- int bookid;
- string name;
- public:
- Sale_item(int i,string j):bookid(i),name(j){}
- Sale_item& operator =(Sale_item &b)
- {
- this->bookid+=b.bookid;
- return *this;
- }
- void out()
- {
- cout<<bookid<<endl;
- }
- };
- int main()
- {
- Sale_item a(1,"luozixuan");
- Sale_item b(8,"luozixuan");
- a=b;
- a.out();
- }
C++ 赋值操作符必须防止自身给自身赋值
我们知道,在C++类中如果出现指针类型的成员,则必须重载赋值操作符来防止浅拷贝问题,那么重载的赋值操作符的实现一般按照这样的步骤:
step1:delete 原来的内存,释放
step2:new 一块合适的新内存,以存放新的内容
step3:把新内容copy到new出来的新内存中,完成拷贝,同时防止了浅拷贝问题
那么,到了这里如何解释“赋值操作符必须防止自身给自身赋值”,原因就在step1那里,假如自己给自己赋值,则在step1的时候,对象的内存就已经被delete掉了,那么在step3的时候,就无法完成拷贝,因为已经被delete掉了
- class A
- {
- public:
- A();
- A(const A &rhs);
- A& operator=(const A &rhs)
- {
-
- delete m_ptr;
- m_ptr = new int[SIZE];
- memcpy(m_ptr,rhs.m_ptr,SIZE);
-
- return *this;
- }
- private:
- int *m_ptr;
- };
函数调用操作符的重载
函数调用操作符是(),因此,此操作符的函数重载是operator()()。重载函数调用操作符的类对象称为函数对象或仿函数(functor),因为我们可以像使用函数名一样使用对象名。
- #include<iostream>
- using namespace std;
- class stuInfo
- {
- public:
- int operator ()(int length,int width)
- {
- return length*width;
- }
- } ;
- int main()
- {
- int a=3;
- int b=2;
- stuInfo stu;
- cout<<"a * b= "<<stu(a,b)<<endl;
- }
当然,也可以将一个函数对象传递给另一个函数,就像传递任何其他对象一样
- #include<iostream>
- using namespace std;
- class stuInfo
- {
- public:
- int operator ()(int length,int width)
- {
- return length*width;
- }
- };
- void getSum(stuInfo& stu)
- {
- int a=2;
- int b=3;
- cout<<"a * b = "<<stu(a,b)<<endl;
- }
- int main()
- {
- stuInfo stu;
- getSum(stu);
- return 0;
- }
函数下标重载
- #include<iostream>
- #include<vector>
- #include<string>
- using namespace std;
- class stuInfo
- {
- private:
- int stuId;
- string stuName;
- public:
- stuInfo(int i,string j):stuId(i),stuName(j){}
- friend ostream& operator <<(ostream& out,const stuInfo& stu);
- };
- ostream& operator <<(ostream& out,const stuInfo& stu)
- {
- out<<"student id: "<<stu.stuId<<"nstudent name: "<<stu.stuName<<endl;
- return out;
- }
- class Team
- {
- private:
- vector<stuInfo> team;
- public:
- stuInfo operator [](const int index)
- {
- return team[index];
- }
- void push(stuInfo stu)
- {
- team.push_back(stu);
- }
- };
- int main()
- {
- Team team;
- team.push(stuInfo(1,"luo"));
- team.push(stuInfo(2,"zi"));
- team.push(stuInfo(3,"xuan"));
- cout<<team[2];
- }
成员访问操作符->的重载
转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=28662931&id=3498450
对象访问成员用“.”,指针访问成员用“->”
箭头(->)操作符,看起来很像二元操作符,左操作数是类对象,右操作数是类成员
函数语句为:
a->b;(其中b可以是函数或者成员;)
步骤1. 如果a是指针,指向一个具有成员b的类对象,那么a->b返回a类型的成员b,至此,语句结束; (因为指针访问就是用->)
步骤2. 如果a是一个对象(对象必须重定义了“operator->”,否则报错)(因为对象去访问用的是.),那么就调用a的operator->()函数,返回值:如果是指针则继续执行步骤1,如果是对象则继续执行步骤2,直到最终走到指针结束。
- #include<iostream>
- using namespace std;
- class A
- {
- public:
- void Print()
- {
- cout<<"this is A!"<<endl;
- }
- };
- class B
- {
- private:
- A a;
- public:
- void Print()
- {
- cout<<"this is B!"<<endl;
- }
- A* operator ->()
- {
- return &a;
- }
- };
- class C
- {
- private:
- B b;
- public:
- void Print()
- {
- cout<<"this is C!"<<endl;
- }
- B* operator ->()
- {
- return &b;
- }
- };
- class D
- {
- private:
- B b;
- public:
- void Print()
- {
- cout<<"this is D!"<<endl;
- }
- B& operator ->()
- {
- return b;
- }
- };
- int main()
- {
- C c;
- c->Print();
- c.operator->()->Print();
- c->operator->()->Print();
- D d;
- d->Print();
- return 0;
- }
c->Print():c是对象,->操作访问重载->函数,返回了b,b是指针,访问其成员函数Print();
c.operator->()->Print():c是对象,.访问其成员函数->operator,返回了b,b是指针,访问其成员函数Print();
c->operator->()->Print():c是对象,(((c->)operator->())->Print())c->,c是对象,->操作访问重载->函数,返回了b,b是指针访问其成员函数operator->(),返回了指针a,指针a访问其成员函数Print();
d->Print():d是对象,->操作访问重载->函数,返回了b,b是对象,->操作访问重载->函数,返回了a,a是指针,访问其成员函数Print();
b.友元函数实现操作符重载
- class 类名
- {
- friend 返回类型 operator 操作符(形参表);
- };
-
- 返回类型 operator操作符(参数表)
- {
-
- }
算术操作符和关系操作符一般重载为非成员函数(若数据成员私有,一般情况下是重载为友元函数)
- #include<iostream>
- #include<string>
- using namespace std;
- class Sale_item
- {
- int bookid;
- int price;
- public:
- friend Sale_item operator +(Sale_item a,Sale_item b);
- void SetItem(int a,int b);
- };
- Sale_item operator +(Sale_item a,Sale_item b)
- {
- int temp=-1;
- if(a.bookid==b.bookid)
- temp=a.price+b.price;
- Sale_item s;
- s.bookid=a.bookid;
- s.price=temp;
- return s;
- }
- void Sale_item::SetItem(int a,int b)
- {
- bookid=a;
- price=b;
- }
- int main()
- {
- Sale_item s1,s2;
- s1.SetItem(1,1);
- s2.SetItem(1,2);
- s1=s1+s2;
- }
友元函数没有this这个隐含的形参,所以传参时需要传两个
对于IO操作符<<,>>的重载,应当使用非成员函数(一般是友元函数)来重载。
为了与标准库IO操作一致,重载 << 操作符函数应把ostream&作为其第一个参数,对类类型const对象的引用作为第二个参数,并返回对ostream形参的引用 ,因为成员函数的第一形参限定为this,所以不能用成员函数来重载输出操作符。istream同理
- #include<iostream>
- #include<string>
- using namespace std;
- class Sale_item
- {
- private:
- int bookid;
- string name;
- public:
- Sale_item(){}
- friend ostream& operator <<(ostream& out,const Sale_item& a);
- friend istream& operator >>(istream& in,Sale_item& a);
- };
- ostream& operator <<(ostream& out,const Sale_item& a)
- {
- out<<"book name: "<<a.name<<"n"<<"book id: "<<a.bookid<<endl;
- return out;
- }
- istream& operator >>(istream& in,Sale_item& a)
- {
- in>>a.bookid>>a.name;
- return in;
- }
- int main()
- {
- Sale_item a;
- cin>>a;
- cout<<a;
- }
函数返回引用如string &,那么它的参数也必须是引用或指针,不能是局部对象。
返回引用部产生对象拷贝,而是返回对象本身。
最后
以上就是俊逸学姐为你收集整理的c++ base-操作符重载的全部内容,希望文章能够帮你解决c++ base-操作符重载所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复