一.运算符重载
定义一个重载运算符就像定义一个函数,只是该函数的名字为operator @ (@代表运算符)
函数参数表中的参数个数取决于两个因素:
1)运算符是一元的还是二元的;
2)运算符被定义为全局函数(一元是一参数,二元是二参)还是成员函数(对于一元函数则没有参数,二元只有一个参数);
#include <iostream>
#include<string.h>
using namespace std;
class CMyPoint
{
int x,y;
public:
CMyPoint(int i,int j){
x=i;y=j;}
CMyPoint operator+(CMyPoint &p)//重载二元运算符
{
return CMyPoint(x+p.x,y+p.y);
}
CMyPoint operator-(CMyPoint &p)//重载二元运算符
{
return CMyPoint(x-p.x,y-p.y);
}
void showPoint()
{
cout<<"x="<<x<<endl;
cout<<"y="<<y<<endl;
}
};
int main()
{
CMyPoint p1(10,0);
CMyPoint p2(0,10);
CMyPoint p3=p1+p2;
CMyPoint p4=p1-p2;
p3.showPoint();
p4.showPoint();
return 0;
}
二.友元重载
使用成员函数重载运算符,若有表达式p=20+p1,
则编译器将解释为:20.operator+(p1),第一个数为整数,现有运算符无法解决;
友元运算符的提出:
有时某些运算符必须重载为友元而不是成员,主要是因为表达式中运算符的顺序问题,因为重载为函数成员时,类对象本身作为第一运算参数;
#include <iostream>
#include<string.h>
using namespace std;
class CMyPoint
{
int x,y;
public:
CMyPoint(int i,int j){
x=i;y=j;}
friend CMyPoint operator+(CMyPoint &p1,CMyPoint &p2)//友元重载
{
return CMyPoint(p1.x+p2.x,p1.y+p2.y);
}
friend CMyPoint operator-(CMyPoint &p1,CMyPoint &p2)//友元重载
{
return CMyPoint(p1.x-p2.x,p1.y-p2.y);
}
friend CMyPoint operator+(int v,CMyPoint &p)
{
return (CMyPoint(p.x+v,p.y+v));
}
void showPoint()
{
cout<<"x="<<x<<endl;
cout<<"y="<<y<<endl;
}
};
int main()
{
CMyPoint p1(10,0);
CMyPoint p2(0,10);
CMyPoint p3=p1+p2;
CMyPoint p4=p1-p2;
p3.showPoint();
return 0;
}
友元重载的单目运算符重载:
friend <返回类型> operator <重载的运算符>(<形参1>)
{
.......}
双目运算符:
friend <返回类型> operator <重载的运算符>(<形参1,形参2>)
{
......}
三.类型转换函数:
转换函数是将一种类型的值转换为另一种类型的值;
C++的类型转换包括自动隐含转换和强制类型转换两种方法;
转换函数是强制转换的一种方式;它是在类中的定义的非静态成员函数,其格式一般如下:
class <类名>
{
public:
operator <类型>();
}
case:
#include<math.h>
#include<iostream>
using namespace std;
class CMyPoint{
int x,y;
public:
CMyPoint(int i,int j){
x=i;
y=j;
}
operator double();
};
CMyPoint::operator double(){
//类型转换函数,将对象强制转化为一个double
return sqrt(x*x+y*y);
}
int main()
{
CMyPoint p1(1,2);
double d=(double)p1;
cout<<d<<endl;
return 0;
}
4.赋值运算符重载
1.相同类型的对象可以直接赋值;
2.并不是所有类型的对象都可以这样赋值的,比如对象中有动态数组或动态数据时就不能相互直接赋值;
分类:
1.缺省的赋值运算符;
2.重载赋值运算符;
class CMyPoint1
{
int x,y;
char *name;
public:
CMyPoint1():x(0),y(0),name(NULL){
}
CMyPoint1(int x,int y,char name[]);
~CMyPoint1();
CMyPoint1& operator=(const CMyPoint1 &r);
}
CMyPoint1::~CMyPoint1()//析构函数实现
{
if(name){
delete[] name;
}
}
CMyPoint1& CMyPoint1::operator =(const CMyPoint1 &r){
//重载赋值运算符
x=r.x;
y=r.y;
if(this->name){
//先查看是否为NULL
delete[] this->name;
this->name=NULL;
}
if(r.name){
//必须name不为NULL才能赋值
this->name=new char[strlen(r.name)+1];
strcpy(this->name,r.name);
}
return *this;//返回一个对象
}
CMyPoint1::CMyPoint1(int i=0,int j=0,char name[])//带参构造函数
{
x=i;
y=j;
if(name){
this->name=new char[strlen(name)+1];
strcpy(this->name,name);
}
}
注意点:
1.赋值运算符重载函数返回的是对象的引用而不是对象;
2.赋值运算符不能重载友元函数,只能是非静态的成员函数;
3.赋值运算符函数是唯一一个不能被继承的运算符函数;
4.在特定的情况下,可以返回const CDemo &。
5.自增自减运算符重载
1.前引:
++i和i++是不一样的,
所以重载运算符时一定要区分开来;
前缀运算符:(++i)
CDemo operator++();
后缀运算符:(i++)
CDemo operator++(int);
input_case:
output_case:
p1:(3,4)
p2:(1,2)
p3:(3,4)
code:
#include<stdio.h>
using namespace std;
class CMyPoint{
int x,y;
public:
CMyPoint(int i,int j){
x=i;
y=j;
}
CMyPoint(){
x=0;
y=0;
}
CMyPoint operator++();//++i
CMyPoint operator++(int);//i++
CMyPoint& operator=(const CMyPoint &r);
int getX();
int getY();
};
int CMyPoint::getX(){
return x;
}
int CMyPoint::getY(){
return y;
}
CMyPoint CMyPoint::operator++(){
//++CMyPoint
x++;
y++;
return *this;
}
CMyPoint CMyPoint::operator++(int){
//CMyPoint++
CMyPoint p(*this);//拷贝函数
x++;y++;
return p;//(先用在加)
}
CMyPoint& CMyPoint::operator=(const CMyPoint &r){
x=r.x;
y=r.y;
return *this;
}//重写赋值运算符
int main()
{
CMyPoint p1(1,2),p2,p3;
p2=p1++;
p3=++p1;
printf("p1:(%d,%d)\n",p1.getX(),p1.getY());
printf("p2:(%d,%d)\n",p2.getX(),p2.getY());
printf("p3:(%d,%d)\n",p3.getX(),p3.getY());
return 0;
}
2.自增自减运算符定义:
前缀自增运算符定义:
CDemo operator++(CDemo &);
CDemo operator–(CDemo &)
后缀自增运算符定义:
CDemo operator++(CDemo &,int);
CDemo operator–(CDemo &,int);
3.不可以重载的运算符:
1)三目运算符:?:
2) 成员运算符:.
3)成员指针运算符:*
4)作用域运算符:::
5)sizeof运算符