32 运算符重载

自定义数据运算方法

复数加法

#include<iostream>
using namespace std;


class Complex {
public:
	int a;
	int b;

	Complex(int a = 0, int b = 0) {
		this->a = a;
		this->b = b;
	}

	void printCom() {
		cout << a << " + " << b << "i" << endl;
	}
};

Complex myAdd(Complex& c1, Complex& c2) {
	Complex tmp(c1.a + c2.a, c1.b + c2.b);
	return tmp;
}

// operator+ 当作函数名
Complex operator+(Complex& c1, Complex& c2) {
    cout << "加号重载" << endl;
	Complex tmp(c1.a + c2.a, c1.b + c2.b);
	return tmp;
}

void main() {
	int a = 0, b = 0;
	int c;
	c = a + b; // 基础数据类型 编译器已知运算规则
	Complex c1(1, 2), c2(3, 4);
	Complex c3;	// 用户自定义数据类型C++编译器不知道如何进行运算
	// c++ 编译器提供机制,让程序员对自定义类型进行运算符操作
	// 运算符重载
	//c3 = c1 + c2;

	// 1
	//Complex c4 = myAdd(c1, c2);
	// 2
	/*Complex c4 = operator+(c1, c2);
	c4.printCom();*/
	// 3
	Complex c4 = c1 + c2;
	c4.printCom();

	// 运算符重载本质是函数调用
}

1 运算符重载语法

类型 类名::operator op(参数表)

Complex operator+(Complex &c1, Complex &c2)

1 二元运算符重载

class Complex {
	// 1 全局函数方法实现"+"重载
	friend Complex operator+(Complex& c1, Complex& c2);
private:
	int a;
	int b;
public:
	Complex(int a = 0, int b = 0) {
		this->a = a;
		this->b = b;
	}

	void printCom() {
		cout << a << " + " << b << "i" << endl;
	}

	// 2 成员函数方法实现"-"重载
	Complex operator-(Complex& c2) {
		Complex tmp(this->a - c2.a, this->b - c2.b);
		return tmp;
	}

};

/*
	全局函数、类成员函数方法实现重载步骤
	写出函数名称
	写出函数参数
	完善返回值(引用,指针,元素)
*/

// 1 全局函数方法实现"+"重载
Complex operator+(Complex& c1, Complex& c2) {
	cout << "加号重载" << endl;
	Complex tmp(c1.a + c2.a, c1.b + c2.b);
	return tmp;
}

void main() {
	Complex c1(1, 2), c2(3, 4);
	
	Complex c3 = c1 + c2;
	c3.printCom();

	
	Complex c4 = c1 - c2;
	c4.printCom();
	//1 全局函数方法实现"+"重载
	// Complex operator+(Complex & c1, Complex & c2);
	
	// 2 成员函数方法实现"-"重载
	//c1.operator-(c2);
	//operator(this, c2)
	//Complex operator(Complex & c2);
}

结果

加号重载
4 + 6i
-2 + -2i

2 一元运算符重载

class Complex {
	// 重载前置++
	friend Complex& operator++(Complex& c1);
	// 重载后置++
	friend Complex operator++(Complex& c1, int);
private:
	int a;
	int b;
public:
	Complex(int a = 0, int b = 0) {
		this->a = a;
		this->b = b;
	}

	void printCom() {
		cout << a << " + " << b << "i" << endl;
	}

	// 前置--
	Complex& operator--() {
		this->a--;
		this->b--;
		return *this;
	}

	// 后置--
	Complex& operator--(int) {
		Complex tmp = *this;
		this->a--;
		this->b--;
		return tmp;
	}


};

/*
	全局函数、类成员函数方法实现重载步骤
	写出函数名称
	写出函数参数
	完善返回值(引用,指针,元素)
*/

// 前置++操作符,用全局函数实现
Complex& operator++(Complex& c1) {
	c1.a++;
	c1.b++;
	return c1;
}

// 后置++操作符,用全局函数实现
Complex operator++(Complex& c1, int) {
	Complex tmp = c1;
	c1.a++;
	c1.b++;
	return tmp;
}

void main() {
	Complex c1(1, 2), c2(3, 4);
    
	// 前置++操作符,用全局函数实现
	++c1;
	c1.printCom();

	// 前置--操作符,成员函数方法
	--c1;
	c1.printCom();

	// 后置++操作符,用全局函数实现
	c1++;
	c1.printCom();

	// 后置--操作符,成员函数方法
	c1--;
	c1.printCom();
}

2 全部改写为成员函数

class Complex {
private:
	int a;
	int b;
public:
	Complex(int a = 0, int b = 0) {
		this->a = a;
		this->b = b;
	}

	void printCom() {
		cout << a << " + " << b << "i" << endl;
	}

	// 2 成员函数方法实现"-"重载
	Complex operator-(Complex& c2) {
		Complex tmp(this->a - c2.a, this->b - c2.b);
		return tmp;
	}

	// 前置--
	Complex& operator--() {
		this->a--;
		this->b--;
		return *this;
	}

	// 后置--
	Complex& operator--(int) {
		Complex tmp = *this;
		this->a--;
		this->b--;
		return tmp;
	}


	// 成员函数方法实现"+"重载
	Complex operator+(Complex& c2) {
		cout << "加号重载" << endl;
		Complex tmp(a + c2.a, b + c2.b);
		return tmp;
	}

	// 前置++操作符,用成员函数实现
	Complex& operator++() {
		a++;
		b++;
		return *this;
	}

	// 后置++操作符,用成员函数实现
	Complex operator++(int) {
		Complex tmp = *this;
		a++;
		b++;
		return tmp;
	}


};

/*
	全局函数、类成员函数方法实现重载步骤
	写出函数名称
	写出函数参数
	完善返回值(引用,指针,元素)
*/


void main() {
	Complex c1(1, 2), c2(3, 4);

	/*Complex c3 = c1 + c2;
	c3.printCom();


	Complex c4 = c1 - c2;
	c4.printCom();*/

	//1 全局函数方法实现"+"重载
	// Complex operator+(Complex & c1, Complex & c2);

	// 2 成员函数方法实现"-"重载
	//c1.operator-(c2);
	//operator(this, c2)
	//Complex operator(Complex & c2);

	// 前置++操作符,用全局函数实现
	++c1;
	c1.printCom();

	// 前置--操作符,成员函数方法
	--c1;
	c1.printCom();

	// 后置++操作符,用成员函数实现
	c1++;
	c1.printCom();

	// 后置--操作符,成员函数方法
	c1--;
	c1.printCom();
}

1 重载<< >>操作符(友元函数)

1 全局函数方法(只能用友元,不能用成员函数)
//void operator<<(ostream& out, Complex& c1) {
//	out << c1.a << " + " << c1.b << "i " << endl;
//}

ostream& operator<<(ostream& out, Complex& c1) {
	out << c1.a << " + " << c1.b << "i " << endl;
	return out;
}


void main() {
	Complex c1(1, 2), c2(3, 4);
	cout << c1;

	// 函数返回值当左值需要返回一个引用
	// ostream类中添加.operator<< 只能用友元函数实现
	cout << c1 << "abcd";
}

C++友元函数不要做 = () [] -> 重载

3 重载=操作符

成员函数重载=

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

class Name {
public:
	Name(const char* myp) {
		m_len = strlen(myp);
		m_p = (char*)malloc(m_len + 1);
		strcpy(m_p, myp);
	}

	// copy构造函数,实现深拷贝
	Name(const Name& obj1) {
		m_len = obj1.m_len;
		m_p = (char*)malloc(m_len + 1);
		strcpy(m_p, obj1.m_p);
	}

	Name& operator=(Name& obj1) {
		// 1 先释放旧内存
		if (this->m_p != NULL) {
			delete[] m_p;
			m_len = 0;
		}
		// 2 根据obj1分配内存大小
		this->m_len = obj1.m_len;
		this->m_p = new char[m_len + 1];
		// 3 把obj1赋值
		strcpy(this->m_p, obj1.m_p);
		return *this;
	}


	~Name() {
		if (m_p != NULL) {
			free(m_p);
			m_p = NULL;
			m_len = 0;
		}
	}

private:
	int m_len;
	char* m_p;
};

void objplay1() {
	Name obj1("abcdefg");
	Name obj2 = obj1;	// 调用自己的构造函数 深拷贝

	Name obj3("obj3");
	obj3 = obj1;		// 重构
	obj1 = obj2 = obj3;

}

void main() {
	objplay1();
}

4 重载数组下标[]

MyArray.h

#pragma once
#include<iostream>
using namespace std;

class Array {
public:
	Array(int length);
	Array(const Array& obj);
	~Array();

	void setData(int index, int value);
	int getData(int index);
	int length();

	// 函数返回值当左值, 需要一个引用 重载[]
	int& operator[](int i);

	// 重载=
	Array& operator=(Array& a1);

	// 重载==
	bool operator==(Array& a1);

	// 重载!=
	bool operator!=(Array& a1);

private:
	int m_length;
	int* m_space;
};

// 重载[] = == !=

MyArray.cpp

#include"MyArray.h"
Array::Array(int length) {
	if (length < 0) {
		length = 0;
	}
	m_length = length;
	m_space = new int[m_length];
}
Array::Array(const Array& obj) {
	this->m_length = obj.m_length;
	this->m_space = new int[this->m_length]; // 分配内存空间
	for (int i = 0; i < obj.m_length; i++) {	// 数组元素复制
		this->m_space[i] = obj.m_space[i];
	}
}
Array::~Array() {
	if (m_space != NULL) {
		delete[]m_space;
		m_length = 0;
	}
}

void Array::setData(int index, int value) {
	m_space[index] = value;
}
int Array::getData(int index) {
	return m_space[index];
}
int Array::length() {
	return m_length;
}

int& Array::operator[](int i) {
	return m_space[i];
}

Array& Array::operator=(Array& a1) {
	// 1 释放原来内存空间
	if (this->m_space != NULL) {
		delete[] m_space;
		m_length = 0;
	}

	// 2 根据a1大小分配内存
	m_length = a1.m_length;
	m_space = new int[m_length];

	// 3 拷贝数据
	for (int i = 0; i < m_length; i++) {
		//m_space[i] = a1.m_space[i];
		m_space[i] = a1[i];
	}
	return *this;
}

bool Array::operator==(Array& a1) {
	if (this->m_length != a1.m_length) {
		return false;
	}
	
	for (int i = 0; i < m_length; i++) {
		if (this->m_space[i] != a1[i]) {
			return false;
		}
	}
}

bool Array::operator!=(Array& a1) {
	/*if (this->m_length == a1.m_length) {
		return false;
	}

	for (int i = 0; i < m_length; i++) {
		if (this->m_space[i] == a1[i]) {
			return false;
		}
	}*/
	/*if (*this == a1) {
		return false;
	}
	else {
		return true;
	}*/
	return !(*this == a1);
}

TestArray.cpp

#include<iostream>
#include"MyArray.h"
using namespace std;

void main() {
	Array a1(10);
	cout << "打印a1" << endl;
	for (int i = 0; i < 10; i++) {
		//a1.setData(i, i);
		// 函数返回值当左值, 需要一个引用
		a1[i] = i;
	}
	for (int i = 0; i < 10; i++) {
		/*cout<<a1.getData(i)<<" ";*/
		cout << a1[i] << " ";
	}

	Array a2 = a1;
	cout << "\n打印a2" << endl;
	for (int i = 0; i < a2.length(); i++) {
		cout << a2.getData(i) << " ";
	}


	Array a3(5);
	/*{
		
		
		a3 = a1;
		a3 = a2 = a1;

		cout << "\n打印a3" << endl;
		for (int i = 0; i < 10; i++) {
			cout << a3[i] << " ";
		}
	}*/

	{
		// 重载 == 
		if (a3 == a1) {
			cout << "\n==\n" << endl;
		}
		else {
			cout << "\n!=\n" << endl;
		}
	}

	{
		// 重载 != 
		if (a3 != a1) {
			cout << "\n!=\n" << endl;
		}
		else {
			cout << "\n==\n" << endl;
		}
	}
}

5 重载括号()

class F {
public:
	int operator()(int a, int b) {
		return a * a + b * b;
	}
};

class F2 {
public:
	int MemFunc(int a, int b) {
		return a * a + b * b;
	}
};

void main() {
	F f;
	f(2, 4);

	F2 f2;
	f2.MemFunc(2, 4);
}

6 不要重载&& || 运算符

C++重载无法实现短路规则

#define  _CRT_SECURE_NO_WARNINGS 
#include <iostream>

using namespace std;

class Test
{
public:
	Test(int value)
	{
		this->value = value;
	}

	int getValue()
	{
		cout << "value = " << this->value << endl;
		return this->value;
	}

	Test& operator+(Test &another)
	{
		//Test temp(0);
		cout << "执行了+重载操作符" << endl;
		Test temp(this->value + another.value);	// 
		//temp.value = this->value + another.value;
		return temp;

	}

	//重载&&操作符  
	bool operator&&(Test &another)
	{
		cout << "执行了&&重载操作符" << endl;
		if (this->value && another.value) {
			return true;
		}
		else{
			return false;
		}
	}
	//重载||操作符  
	bool operator||(Test &another)
	{
		cout << "执行了||重载操作符" << endl;
		if (this->value || another.value) {
			return true;
		}
		else {
			return false;
		}
	}
private:
	int value;
};

int main(void)
{
	int a = 10;
	int b = 20;

	a = 0;

	//普通的&& 和||会有短路的现象
	if (a && (a = 20)) //&& 如果遇见非逻辑 直接退出
	{
		
	}

	cout << "a = " << a << endl;

	a = 10;
	if (a || (a = 20)) //&& 如果遇见是 逻辑 直接退出
	{

	}
	cout << "a = " << a << endl;


	cout << " --------   " << endl;


	Test t1(0);
	Test t2(20);

	if (t1.getValue() && (t1 + t2).getValue() ) //普通&& 会短路现象
	{
		cout << "if 进入成功" << endl;
	}


	cout << " --------   " << endl;


	if (t1 && (t1 + t2))// t1.operator&&(    t1.operator+(t2)   ) //我们重载的&&不会发生短路现象。
	{
		cout << "if 进入成功" << endl;
	}


	cout << " --------   " << endl;


	if (t2 || (t1 + t2)) //t1.operator|| (  t1.operator+(t2)    ) 
	{
		cout << "if 进入成功" << endl;

	}



	
	return 0;
}

结果

a = 0
a = 10
 --------
value = 0
 --------
执行了+重载操作符
执行了&&重载操作符
 --------
执行了+重载操作符
执行了||重载操作符
if 进入成功

7 字符串类

要求: MyString a; MyString a(“add”); MyString b = a;

常用操作符: << >> != == > < =

MyString.h

#pragma once
#include<iostream>
using namespace std;
// c中没有字符串 字符串类(c风格)
class MyString {
	friend ostream& operator<<(ostream& out, MyString& s);
	friend istream& operator>>(istream& in, MyString& s);
public:
	MyString(int len = 0);
	MyString(const char* p);
	MyString(const MyString& obj);
	~MyString();
	// 重载=
	MyString& operator=(MyString& s);
	MyString& operator=(const char* p);
	// 重载[]
	char& operator[](int index);
	
	// 重载==
	bool operator==(const char* p) const;
	bool operator==(MyString& s) const;
	// 重载!=
	bool operator!=(const char* p) const;
	bool operator!=(MyString& s) const;
	// 重载<
	int operator<(const char* p)const;
	int operator<(MyString& s)const;
	// 重载>
	int operator>(const char* p)const;
	int operator>(MyString& s)const;

// 让类指针可以在外部访问
	char* c_str() {
		return m_p;
	}
	const char* c_str2() {
		return m_p;
	}
	int length() {
		return m_len;
	}

private:
	int m_len;
	char* m_p;
	
};

MyString.cpp

#define  _CRT_SECURE_NO_WARNINGS
#include"MyString.h"

// 重载<<
ostream& operator<<(ostream& out, MyString& s) {
	out << s.m_p;
	return out;
}

// 重载>>
istream& operator>>(istream& in, MyString& s) {
	in >> s.m_p;
	return in;
}

MyString::MyString(int len) {
	if (len == 0) {
		m_len = len;
		m_p = new char[m_len + 1];
		strcpy(m_p, "");
	}
	else {
		m_len = len;
		m_p = new char[m_len + 1];
		memset(m_p, 0, m_len);
	}
	
}

MyString::MyString(const char* p) {
	if (p == NULL) {
		m_len = 0;
		m_p = new char[m_len + 1];
		strcpy(m_p, "");
	}
	else {
		m_len = strlen(p);
		m_p = new char[m_len + 1];
		strcpy(m_p, p);
	}
}

// copy 构造函数
MyString::MyString(const MyString& s) {
	m_len = s.m_len;
	m_p = new char[m_len + 1];
	strcpy(m_p, s.m_p);
}

MyString::~MyString() {
	if (m_p != NULL) {
		delete[] m_p;
		m_p = NULL;
		m_len = 0;
	}
}


MyString& MyString::operator=(MyString& s) {
	// 1 释放旧内存
	if (this->m_p != NULL) {
		delete[] m_p;
		m_len = 0;
	}
	// 2 根据s分配内存
	
	m_len = s.m_len;
	m_p = new char[m_len + 1];
	strcpy(m_p, s.m_p);
	return *this;
}

// s4 = "s22";
MyString& MyString::operator=(const char* p) {
	// 1 释放旧内存
	if (this->m_p != NULL) {
		delete[] m_p;
		m_len = 0;
	}
	// 2 根据p分配内存
	if (p == NULL) {
		m_len = 1;
		m_p = new char[m_len];
		strcpy(m_p, "");
	}
	else {
		m_len = strlen(p);
		m_p = new char[m_len + 1];
		strcpy(m_p, p);
	}
	return *this;
}

// 重载[]
char& MyString::operator[](int index) {
	return m_p[index];
}


// 重载==
bool MyString::operator==(const char* p) const {
	
	if (p == NULL) {
		if (m_len == 0) {
			return true;
		}
		else {
			return false;
		}
	}
	else {
		if (m_len == strlen(p)) {
			return !strcmp(m_p, p);
		}
		else {
			return false;
		}
	}
}
bool MyString::operator==(MyString& s) const {
	if (m_len != s.m_len) {
		return false;
	}
	
	return !strcmp(m_p, s.m_p);
}
// 重载!=
bool MyString::operator!=(const char* p) const {
	return !(*this == p);
}
bool MyString::operator!=(MyString& s) const {
	return !(*this == s);	
}

// 重载<
int MyString::operator<(const char* p)const {
	return strcmp(m_p, p);
}
int MyString::operator<(MyString& s)const {
	return strcmp(m_p, s.m_p);
}
// 重载>
int MyString::operator>(const char* p)const {
	return strcmp(p, m_p);
}
int MyString::operator>(MyString& s)const {
	return strcmp(s.m_p, m_p);
}

MyString_Test.cpp

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include"MyString.h"

void main() {
	MyString s1;
	MyString s2("ccc");
	MyString s2_2 = NULL;
	MyString s3 = s2;
	MyString s4 = "s4444";

	// 运算符重载 和 重载[]
	// = 
	s4 = s2;
	s4 = "s22";

	s4[0] = 'a';
	cout << s4[0] << endl;

	cout << s4 << endl;

	
	if (s2 == "s2") {
		cout << "=" << endl;
	}
	else {
		cout << "!=" << endl;
	}

	if (s2 == s3) {
		cout << "=" << endl;
	}
	else {
		cout << "!=" << endl;
	}


	/*if (s3 < "bbb") {			不能直接比较,strcmp返回值a<b返回负值也会判断为真
		cout << "小于" << endl;
	}
	else {
		cout << "不等于" << endl;
	}*/

	int tag = (s3 < "bbb");
	if (tag < 0) {
		cout << "小于" << endl;
	}
	else if (tag > 0) {
		cout << "大于" << endl;
	}
	else {
		cout << "等于" << endl;
	}
	tag = (s3 < s2);
	if (tag < 0) {
		cout << "小于" << endl;
	}
	else if (tag > 0) {
		cout << "大于" << endl;
	}
	else {
		cout << "等于" << endl;
	}

	MyString s5("aaaaaaa");
	cout << "s5:" << s5 << endl;
	strcpy(s5.c_str(), "abc");
	cout << "s5:" << s5 << endl;

	MyString s6(128);
	cout << "\n请输入字符串(回车结束)";
	cin >> s6;
	cout << s6 << endl;
}

结果

a
a22
!=
=
大于
等于
s5:aaaaaaa
s5:abc

请输入字符串(回车结束)13456abc
13456abc
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值