运算符重载的本质理解和数组运算符重载的实现

こ雲淡風輕ζ 提交于 2019-12-28 10:14:31

【推荐】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;
}

最后希望能对大家有帮助,沙米才疏学浅,有什么错误请留言指正,谢谢大家。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!