运算符重载

作用:
1、直观自然,可以提高程序的可读性
2、体现了C++的可扩充性
3、运算符重载仅仅只是语法上的方便,它是另一种函数调用的方式
4、运算符重载,本质上是函数重载

注意事项:不要滥用重载,因为它只是语法上的方便,所以只有在涉及的代码更容易写、尤其是更容易读时才有必要重载

成员函数:
成员函数原型的格式:

函数类型 operator运算符(参数表);

成员函数定义的格式:

函数类型 类名::operator运算符(参数表)
{
   函数体;
}

友元函数:
友元函数的原型:

friend 函数类型operator运算符(参数表);

友元函数定义的格式:

friend 函数类型 类名::operator运算符(参数表)
{
    函数体;
}

运算符重载规则:
1、运算符重载不允许发明新的运算符
2、不能改变运算符操作对象的个数
3、运算符被重载后,其优先级和结合性不会改变
4、不能重载的运算符在这里插入图片描述

5、成员函数重载和友元函数重载的选择

  1. 一般情况下,单目运算符最好重载为类的成员函数;双目运算符则最好重载为类的友元函数。
  2. 以下一些双目运算符不能重载为类的友元函数:=、()、[] 、 ->
  3. 类型转换运算符只能以成员函数方式重载(没有参数,不能指定返回类型)
  4. 流运算只能以友元的方式重载(为什么:如果是重载双目操作符(即为类的成员函数),就只要设置一个参数作为右侧运算量,而左侧运算量就是对象本身,而 >> 或<< 左侧运算量是 cin或cout 而不是对象本身,所以不满足后面一点,就只能申明为友元函数了)

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include<string.h>
//> < = << >>要会写
using namespace std;

class MyString
{
public:

	MyString()
	{
		this->num = 0;
		this->ptr = nullptr;

		cout << "调用无参构造函数" << endl;
	}

	explicit MyString(const char* ptr)
	{
		this->num = 0;
		int len = strlen(ptr);
		this->ptr = new char[len + 1];
		strcpy(this->ptr, ptr);

		cout << "调用有参构造函数" << endl;
	}

	explicit MyString(const MyString& other)
	{
		this->num = 0;
		int len = strlen(other.ptr);
		this->ptr = new char[len + 1];
		strcpy(this->ptr, other.ptr);

		cout << "调用拷贝构造函数" << endl;
	}

	MyString(int num)
	{
		this->num = num;
		this->ptr = nullptr;

		cout << "调用类型转换构造函数" << endl;
	}

	MyString(MyString&& other)
	{
		this->num = 0;
		this->ptr = other.ptr;
		other.ptr = nullptr;

		cout << "调用移动拷贝构造函数" << endl;
	}

	~MyString()
	{
		if (ptr != nullptr)
		{
			delete[]ptr;
		}
		cout << "调用析构函数" << endl;
	}

friend MyString & operator+(const MyString& s1,const MyString& s2);

friend bool operator>(const MyString& s1, const MyString &s2);

friend bool operator<(const MyString& s1, const MyString& s2);

//特殊运算符
	 //赋值运算符=//如果没有重载(且没有移动拷贝构造函数),系统会默认重载,必须以成员函数重载//注意:默认生成的拷贝是浅拷贝;


MyString& operator=(const MyString& other)  //赋值运算符=                
{
	if (this != &other)
	{
		int len = strlen(other.ptr);
		this->ptr = new char[len + 1];
		strcpy(this->ptr, other.ptr);
	}
	return *this;
}
//移动赋值运算符重载:解决临时对象拷贝开销的问题
MyString& operator=(MyString&& other)//移动赋值运算符重载
{
	this->ptr = other.ptr;
	other.ptr = nullptr;
	return *this;
}

char& operator[](int index) //[]:是双目运算符,但是必须以成员函数重载
{
	return (this->ptr)[index];
}


MyString& operator+=(const MyString& other)  //+=:利用+实现+=
{
	*this = *this + other;
	return *this;
}

//!:单目运算符,只能用成员函数重载
bool operator!()
{
	return strlen(this->ptr) != 0;
}

//类型转换运算符:static_cast 
operator int()
{
	return atoi(this->ptr);
}

operator char()
{
	return (this->ptr)[0];
}

//流运算符:必须是友元函数重载    cin对象---istream cout对象---ostream
//输出流<<

friend ostream& operator<<(ostream& out, const MyString& s);

//输入流>>

friend istream& operator>>(istream& in, MyString& s);

//i++,++i



int num;
char* ptr;
};
class Test
{
public:
	int num;

	//++i
	Test& operator++()
	{
		(this->num)++;
		return *this;
	}
	//i++
	Test& operator++(int num)//带参的
	{
		Test temp = *this;
		(this->num)++;
		return temp;
	}
};

MyString& operator+(const MyString& s1, const MyString& s2)
{
	int len1 = strlen(s1.ptr);
	int len2 = strlen(s2.ptr);

	//char* s3 = new char[len1 + len2 + 1];
	MyString* s3 = new MyString;
	s3->ptr = new char[len1 + len2 + 1];
	strcpy(s3->ptr, s1.ptr);

	strcat(s3->ptr, s2.ptr);

	return *s3;
}
bool operator>(const MyString&s1, const MyString &s2)
{
	if (strcmp(s1.ptr, s2.ptr) >0)
	{
		return true;
	}
	return false;
}

bool operator<(const MyString& s1, const MyString& s2)
{
	if (strcmp(s1.ptr, s2.ptr) < 0)
	{
		return true;
	}
	return false;
}

 ostream& operator<<(ostream& out, const MyString& s)
{
	out << s.ptr;
	return out;
}

istream& operator>>(istream& in, MyString& s)
{
	string temp;
	in >> temp;
	const char* mtr = temp.c_str();
	s.ptr = new char[temp.size() + 1];
	strcpy(s.ptr, mtr);

	return in;
}




int main()
{
	MyString ms1("hello");
	MyString ms2("world");
	/*
	MyString ms3 = ms1 + ms2;

	if (ms1 > ms2)
	{
		cout << "true" << endl;
	}

	if (ms1 < ms2)
	{
		cout << "true" << endl;
	}*/
	MyString ms3 = ms2;//拷贝构造函数//MyString ms3(ms2);
	ms3 = ms2;//赋值运算符
	ms3 += ms2;
	cout << ms1.ptr << endl;
	cout << ms3[2] << endl;
	if (!ms3)
	{

	}
	MyString ms4("123456");

	int num = static_cast<int>(ms4);

	char ch = static_cast<char>(ms4);
	cout << num << endl;

	cout << ms4 << endl;//流运算符<<输出流运算符 >>输入流运算符

	MyString ms5;
	cin >> ms5;
	
	Test t1;
	t1.num = 5;
	
	t1++;
	++t1;


	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

&*Savior

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

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

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

打赏作者

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

抵扣说明:

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

余额充值