【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
了解了运算符重载,就会觉得其十分的简单。
所谓重载,就是重新赋予新的意义。函数重载就是对于一个已有的函数重新赋予新的含义,使之实现新的功能。运算符也可以重载,在我们进行整数间的加法时,C++编译器已经对+运算符进行了重载。又如我们在使用位运算符<<、>>进行输入和输出操作时,C++系统已经分别重载了流对象cin和cout的<<、>>运算符,我们只需引入头文件iostream(当然还应当包括”using namespace std“)。
运算符重载的设计初衷
由于每个数据类型都有自己的运算符规则,C++编译器只是重载了基本数据类型的的运算符,对于复杂的数据类型(自定义的类),由于其定义者对其的运算规则要求不同,所以C++编译器就把重载复杂数据类型运算符的任务交给了其定义者,定义者可以根据自己的需要重载复杂数据类型的运算符。
运算符重载本质
就是一个函数,用来重新定义复杂的数据类型实例对象(同类型)间运算规则的函数。
运算符重载的使用
使用的两种方式:1、全局函数实现 2、类的成员函数实现
使用步骤(按照这个步骤来就很简单)
1)要承认操作符重载是一个函数,写出函数名称operator+ ()
2)根据操作数,写出函数参数(如果全局函数实现,要多一个这类的对象参数;如果是成员函数,少一个这类的对象参数)
3)根据业务,完善函数返回值(看函数是返回引用 还是指针 元素),及实现函数业务
实现数组运算符重载代码
下面的例子是实现了自定义数组的 =(包括链式)、[]、== 、!=的运算符重载
数组类头文件 ArrayCls.h
#pragma once
#include <iostream>
using namespace std;
class ArrayCls
{
public:
ArrayCls(int lengh);
ArrayCls( ArrayCls& obj);
int length();
int getData(int i);
void setData(int i,int j);
int& operator[](int num); //[]运算符重载,可以根据下标获取数据,也可设置数据
bool operator==(ArrayCls& arr1); //==运算符重载,判断数组的两个对象是否相等
bool operator!=(ArrayCls& arr1); //!=运算符重载,判断数组的两个对象是否不相等
ArrayCls& operator=(ArrayCls& arr1); //=赋值运算符重载,将数组的对象赋值给另一个数组对象
friend ostream& operator<<(ostream& out,ArrayCls arr1); // <<左移运算符重载,输出数组的数据到屏幕中
friend istream& operator>>(istream& in,ArrayCls& arr1); // >>右移运算符重载,从屏幕中给数组中的元素赋值
~ArrayCls(void);
private:
int mLength;
int *mSpace;
};
数组cpp文件 ArrayCls.cpp
#include "ArrayCls.h"
#include <string.h>
ArrayCls::ArrayCls(int lengh)
{
mLength = lengh;
mSpace = new int[lengh];
}
ArrayCls::ArrayCls(ArrayCls& obj)
{
mLength = obj.length();
mSpace = new int[mLength];
for(int i=0; i<mLength; i++)
{
this->setData(i,obj.getData(i));
}
}
int ArrayCls::length()
{
return mLength;
}
int ArrayCls::getData(int i)
{
return mSpace[i];
}
void ArrayCls::setData(int i,int j)
{
mSpace[i] = j;
}
int& ArrayCls::operator[](int num)
{
return this->mSpace[num];
}
bool ArrayCls::operator==(ArrayCls& arr1)
{
int i = 0,len = this->length();
if(len != arr1.length())
return false;
for(i=0; i<len; i++)
{
if(this->mSpace[i] != arr1[i])
{
return false;
}
}
return true;
}
bool ArrayCls::operator!=(ArrayCls& arr1)
{
return !(arr1 == *this);
}
ArrayCls& ArrayCls::operator=(ArrayCls& arr1)
{
int i=0, len=arr1.length();
//清理this的内存
if(this->mSpace != NULL)
{
delete []this->mSpace;
}
//给this分配内存
this->mSpace = new int[arr1.length()];
//赋值
for(i=0; i<len; i++)
{
this->mSpace[i] = arr1[i];
}
this->mLength = len;
return *this;
}
ArrayCls::~ArrayCls(void)
{
if(mSpace != NULL)
{
delete []mSpace;
mSpace = NULL;
mLength = -1;
}
}
main文件
#include <iostream>
using namespace std;
#include "ArrayCls.h"
/* 使用友元函数重载<<运算符 ,因为此两目运算的左操作量不是对象本身,而是ostream的,
所以需要通过友元函数访问对象的私有成员。*/
ostream& operator<<(ostream& out,ArrayCls arr1)
{
int i=0, len=arr1.mLength;
for(i=0; i<len; i++)
{
out<<arr1[i]<<" ";
}
out<<" len="<<len<<endl;
return cout;
}
/* 使用友元函数重载istream的>>运算符*/
istream& operator>>(istream& in,ArrayCls& arr1)
{
int i=0,len = arr1.mLength;
for(i=0; i<len; i++)
{
cin>>arr1[i];
}
return cin;
}
int main()
{
int i=0,j=0;
ArrayCls arr = ArrayCls(20);
/*没有使用运算符重载 设置、获取数组*/
for(i=0; i<arr.length();i++)
{
arr.setData(i,2*i+1);
}
for(i=0; i<arr.length();i++)
{
j = arr.getData(i);
cout<<" "<<j;
}
cout<<endl; //输出 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39
/*[]运算符重载 arr[1]—>获取值 arr[1]=1 —>设置值 函返回值当左值,需要返回一个引用*/
//arr[1] = 5 int& operator[](int num);
arr[1] = 5;
cout<<"arr[1]="<<arr[1]<<endl; //输出 arr[1]=5
/* ==运算符重载 */
//arr1==arr2 bool operator==(ArrayCls& arr1);
ArrayCls arr1 = ArrayCls(5);
ArrayCls arr2 = ArrayCls(5);
for(i=0; i<arr1.length();i++)
{
arr1[i] = 2*i;
arr2[i] = 3*i;
}
if(arr1 == arr2)
{
cout<<"arr1 == arr2"<<endl;
}
else
{
cout<<"arr1 != arr2"<<endl;
} //输出 arr1 != arr2
/* != 运算符重载 */
//arr1 != arr2 bool operator!=(ArrayCls& arr1);
if(arr1 != arr2)
{
cout<<"arr1 != arr2"<<endl;
}
else
{
cout<<"arr1 == arr2"<<endl;
} //输出 arr1 != arr2
/* =运算符重载 */
//arr1=arr2=arr3 链式返回一个引用 ArrayCls& operator=(ArrayCls& arr1);
ArrayCls arr3 = ArrayCls(1);
arr3 = arr2 = arr1;
for(i=0; i<arr3.length();i++)
{
cout<<i<<":arr3="<<arr3[i]<<" arr2="<<arr2[i]<<" arr1="<<arr1[i]<<endl;
}
/* 输出: 0:arr3=0 arr2=0 arr1=0
1:arr3=2 arr2=2 arr1=2
2:arr3=4 arr2=4 arr1=4
3:arr3=6 arr2=6 arr1=6
4:arr3=8 arr2=8 arr1=8*/
/* << 输出运算符重载 */
/* cout<<arr1 ostream& operator<<(ostream& out,ArrayCls arr1);
注意:这个双目运算符的左侧运算量是 cout,不是ArrayCls类的对象本身,我们就只能使用友元函数来访问对象的私有成员*/
cout<<arr1; //输出 0 2 4 6 8 len=5
/* >> 输入运算符重载*/
/* cin>>arr1 istream& operator>>(istream& in,ArrayCls& arr1);
注意:这个双目运算符的左侧运算量是 cin,不是ArrayCls类的对象本身,我们就只能使用友元函数来访问对象的私有成员*/
cin>>arr1;
cout<<arr1;
system("pause");
return 0;
}
实现字符串运算符重载代码
本实例实现了字符串的=、==、<<(输出)、>>(输入)、<(小于)、>(大于)运算符的重载
MyString类 头文件
#pragma once
#include <iostream>
using namespace std;
class MyString
{
public:
MyString(void);
MyString(char *pStr);
void printString(); //打印字符串函数
MyString& operator=(MyString &str); // =运算符
bool operator==(MyString &str); // ==运算符
bool operator<(MyString &str); // <运算符
bool operator>(MyString &str); // >运算符
friend ostream& operator<<(ostream& cout,MyString& str);//左移运算符重载的友元函数
friend istream& operator>>(istream& cin,MyString& str); //右移运算符重载的友元函数
~MyString(void);
private:
int m_iLen;
char *m_pSpace;
};
MyString类 cpp文件
#include "MyString.h"
#include <iostream>
using namespace std;
MyString::MyString(void)
{
m_iLen = 1;
m_pSpace = new char[m_iLen];
m_pSpace[m_iLen-1] = '\0';
}
MyString::MyString(char *pStr)
{
m_iLen = strlen(pStr)+1;
m_pSpace = new char[m_iLen];
strcpy(m_pSpace,pStr);
}
void MyString::printString()
{
cout<<"MyString :"<<m_pSpace<<endl;
}
MyString& MyString::operator=(MyString &str)
{
if(m_pSpace != NULL)
{
delete []m_pSpace;
}
m_iLen = str.m_iLen;
m_pSpace = new char[m_iLen];
strcpy(m_pSpace,str.m_pSpace);
return *this;
}
bool MyString::operator==(MyString &str)
{
if(this->m_iLen != str.m_iLen)
{
return false;
}
if(strcmp(this->m_pSpace,str.m_pSpace) == 0)
{
return true;
}
return false;
}
bool MyString::operator<(MyString &str)
{
if(strcmp(this->m_pSpace,str.m_pSpace) < 0)
{
return true;
}
return false;
}
bool MyString::operator>(MyString &str)
{
if(strcmp(this->m_pSpace,str.m_pSpace) > 0)
{
return true;
}
return false;
}
MyString::~MyString(void)
{
if(m_pSpace != NULL)
{
delete []m_pSpace;
m_pSpace = NULL;
m_iLen = -1;
}
}
操作字符串main文件
#include <iostream>
using namespace std;
#include "MyString.h"
//左移运算符重载,cout不是MyString类的对象本身,我们就只能使用友元函数来访问对象的私有成员
ostream& operator<<(ostream& cout,MyString& str)
{
cout<<str.m_pSpace;
return cout;
}
//右移运算符重载,cin不是MyString类的对象本身,我们就只能使用友元函数来访问对象的私有成员
istream& operator>>(istream& cin,MyString& str)
{
char temp[1024] = {0};
cin>>temp;
str = MyString(temp);
return cin;
}
int main()
{
//构造函数
MyString str = MyString("asdfasdf");
str.printString();
// =运算符 MyString& operator=(MyString &str)
MyString str2 = str;
str2.printString();
// <<运算符 ostream& operator<<(ostream os,MyString& str);
cout<<"str2:"<<str2<<endl;
// >>运算符 istream& operator>>(istream& cin,MyString& str);
MyString str3,str4;
cin>>str3>>str4;
cout<<"str3:"<<str3<<" str4:"<<str4<<endl;
// ==运算符 bool operator==(MyString &str);
if(str3 == str4)
{
cout<<"str3 == str4"<<endl;
}
else
{
cout<<"str3 != str4"<<endl;
}
// <运算符 bool operator<(MyString &str);
if(str3 < str4)
{
cout<<"str3 < str4"<<endl;
}
else
{
cout<<"str3 !< str4"<<endl;
}
// >运算符 bool operator>(MyString &str);
if(str3 > str4)
{
cout<<"str3 > str4"<<endl;
}
else
{
cout<<"str3 !> str4"<<endl;
}
system("pause");
return 0;
}
最后希望能对大家有帮助,沙米才疏学浅,有什么错误请留言指正,谢谢大家。
来源:oschina
链接:https://my.oschina.net/u/1783725/blog/665413