C++运算符重载

  • C++基本运算符:

        只能用于基本数据类型的运算符,无法进行对象间的计算,方便起见引入了运算符重载。

  • 重载运算符:
  1. 就是对已有的运算符进行重定义,赋予其另一种功能,以适应不同的数据类型运算(比如结构体、对象之间的运算)。
  2. 重载运算符是具有特殊名字的函数,它们的名字由关键字operator和其后面要定义的运算符号共同组成,且重载的运算符函数也包含返回类型参数列表函数体。
  3. 重载运算符写法就是:
返回类型 函数名(重载的运算符)  (参数)
  • 加号运算符重载:
class Person
{
public:
    //构造函数
	Person(string name, int age)
	{
		this->p_name = name;
		this->p_age = age;
	}

	//运算符重载 也可以发生函数重载
  //返回类型 函数名   参数类型 引用数据类型
	Person operator+ (Person &pSource)
	{
		Person pNew;
		pNew.p_name = "none";
		pNew.p_age = this->p_age + pSource.p_age;
		return pNew;
	}

	//全局函数重载:
	//Person operator+ (Person &p1, Person &p2);
private:	
	string p_name;
	int p_age;
};

void text1()
{
	Person zhang("sige", 18);
	Person gu("shuai", 22);

    //第一种写法:函数调用
	//Person d = zhang.operator+(gu);
    //第二种写法:简化写法
	Person d = zhang + gu;
}

像上面这样子实现时,进行对象之间的加法,实际就是调用了对象内的运算符重载函数。

  • 左移运算符重载:
//标准输出流  函数名     标准输出流    需要操作的对象
    ostream& operator<<(ostream &cout, Person &p)
  • 这里的左移运算符的重载目的是 实现直接输出对象中的数据内容 
class Person
{
    //友元,使类外函数可以访问本类内所有内容
	friend ostream& operator<<(ostream &cout, Person &p);
public:

	Person(string name, int age)
	{
		this->p_name = name;
		this->p_age = age;
	}

private:	
	string p_name;
	int p_age;
};


ostream& operator<<(ostream &cout, Person &p)
{
	cout << "m_name = " << p.p_name << " p_age = " << p.p_age;
	return cout;
}

void text2()
{
	Person zhang("sige", 18);
	cout << zhang << endl;
}
  • 注意:
  • cout的数据类型是ostream(标准输出流),这里想要实现左移运算符在对象之前的重载操作,就需要将cout作为参数传入函数中;同时该函数不能是类的成员函数,需要作为全局函数来实现(我是这么理解的)
  • 最后返回cout是将标准输出流返回,目的是实现调用时的链式访问。
  • 同时类外的函数要方位类内的私有内容,可以使用友元的方式来给他操作权限

  • 递增运算符重载(递减同理)
class Table1
{
    friend ostream & operator<<(ostream& cout, Table1& p);
public:
	Table1()
	{
		tAge = 18;
	}

    //前置递增
    Table1& operator++()
	{
		tAge++;
		return *this;
	}

    //后置递增
	Table1 operator++(int)
	{
		Table1 temp = *this;
		this->tAge++;
		return temp;
	}

private:
	int tAge;
};

//这个是打印函数(重载运算符)
ostream & operator<<(ostream& cout, Table1& p)
{
	cout << "tAge = " << p.tAge << endl;
	return cout;
}


void test1()
{
	//重载++
	Table1 p1(10);

    //测试
	cout << ++p1 << endl;
	cout << p1++ << endl;
	cout << p1 << endl;
}
  • 注意:
  • 递增运算符实现时应分为前置递增后置递增两种
  • 前置递增的实现是先进行自增运算,再将结果返回
  • 后置递增的实现是储存递增前的对象,将结果递增后,返回之前存储的对象
  • 前置递增返回值是自身,后置递增返回的值是一个新的对象(通过拷贝构造函数)。

  • 重载赋值运算符:
class Table2
{
	friend ostream & operator<<(ostream& cout, Table2& p);
public:
    //构造
	Table2(int length)
	{
		tAge = 18;
		this->length = new int(length);
	}

    //赋值运算符重载
	Table2& operator=(Table2 &p)
	{
		this->tAge = p.tAge;
		if (this->length != nullptr)
		{
			delete this->length;
            this->length = nullptr;
		}
		
        this->length = new int(*(p.length));
		
		return *this;
	}

	~Table2()
	{
		if (length != nullptr)
		{
			delete length;
		}	
	}
private:
	int tAge;
	int* length;
};

//打印输出函数
ostream & operator<<(ostream& cout, Table2& p)
{
	cout << "tAge = " << p.tAge << " length = " << *(p.length);
	return cout;
}

void test2()
{
	//重载 = 
	Table2 p1(10);
	Table2 p2(20);	//必须先初始化,否则野指针
	p2 = p1;
	cout << p2 << endl;
}

  • 注意:
  • 当类内存在堆区开辟的内存空间,在赋值时需要先保证之前的空间已被释放;且拷贝堆区空间数据时,必须重新开辟空间,以保证析构时不会重复释放内存(类似与拷贝构造函数)。

  • 重载== 和 !=运算符
class Table2
{
	friend ostream & operator<<(ostream& cout, Table2& p);
public:
	Table2(int length)
	{
		tAge = 18;
		this->length = new int(length);
	}

	bool operator==(Table2& p)
	{
		if (this->tAge == p.tAge &&
			*this->length == *p.length)
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	bool operator!=(Table2& p)
	{
		if (this->tAge != p.tAge ||
			*this->length != *p.length)
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	~Table2()
	{
		if (length != nullptr)
		{
			delete length;
		}	
	}
private:
	int tAge;
	int* length;
};

ostream & operator<<(ostream& cout, Table2& p)
{
	cout << "tAge = " << p.tAge << " length = " << *(p.length);
	return cout;
}

void test3()
{
	//重载 == !=
	Table2 p1(10);
	Table2 p2(20);	//必须先初始化,否则野指针
	if (p1 == p2)
	{
		cout << "p1 == p2" << endl;
	}

	if (p1 != p2)
	{
		cout << "p1 != p2" << endl;
	}
}

这个没啥好注意的,比较简单,就是简单的比较操作。

  • 重载()仿函数
  • 目的是实现一种简写的方法
class MyPrint
{
public:
	int operator()(string text, int num1, int num2)
	{		
		cout << text << endl;
		return num1 + num2;
	}
};

void test4()
{
	//重载() 仿函数
	MyPrint a;
	a.operator()("我爱大又白", 1, 1);
    //这里在函数内打印text文本

    //这里是该函数的简化调用方式
	cout << a("我爱嗨丝", 2, 18) << endl;
    //这里在函数内打印文本,且在函数外打印函数返回值

	//匿名函数对象调用
	cout << MyPrint()("asas", 1, 2) << endl;
}

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KamikazePilot

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值