【黑马程序员】C++运算符重载

文章目录

运算符重载

  • 对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型

  • 对于内置的数据类型的表达式的运算符是不可能改变的

  • 不要滥用运算符重载

加号运算符重载

  • 可以计算自定义数据类型

成员函数实现运算符重载

  • 成员函数实现运算符重载的本质 p2.operator(p1)
cpp 复制代码
#include <iostream>

using namespace std;

class Person{
public:
	Person(){}
	Person(int a, int b) {
		this->a=a;
		this->b=b;
	}
	// 成员函数实现运算符重载
	Person operator+(const Person& p) {
		Person temp;
		temp.a=this->a+p.a;
		temp.b=this->b+p.b;
		return temp;
	}
public:
	int a;
	int b;
};

void test() {
	Person p1(10,10);
	Person p2(10,10);
	// 成员函数实现运算符重载的本质 p2.operator(p1)
	Person p3 = p1+p2;
	cout << "p3.a: " << p3.a << endl;
	cout << "p3.b: " << p3.b << endl;
}

int main(){
	test();
	return 0;
}

全局函数实现运算符重载

  • 全局函数实现运算符重载的本质是operator+(p1,p2)
cpp 复制代码
#include <iostream>

using namespace std;

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

// 全局函数实现运算符重载
Person operator+(Person p1, Person p2) {
	Person temp;
	temp.a=p1.a+p2.a;
	temp.b=p1.b+p2.b;
	return temp;
}
// 全局函数实现函数重载

void test() {
	Person p1(10,10);
	Person p2(10,10);
	// 全局函数实现运算符重载的本质是operator+(p1,p2)
	Person p3 = p1+p2;
	cout << "p3.a: " << p3.a << endl;
	cout << "p3.b: " << p3.b << endl;
}

int main(){
	test();
	return 0;
}

全局函数实现函数重载

  • 通过函数重载实现不同类型的加法运算
cpp 复制代码
#include <iostream>

using namespace std;

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

// 全局函数实现函数重载
Person operator+(Person p1, int num) {
	Person temp;
	temp.a=p1.a+num;
	temp.b=p1.b+num;
	return temp;
}

void test() {
	Person p1(10,10);
	int num = 100;
	// 通过函数重载实现了Person和int类型的加法运算
	Person p3 = p1+num;
	cout << "p3.a: " << p3.a << endl;
	cout << "p3.b: " << p3.b << endl;
}

int main(){
	test();
	return 0;
}

左移运算符重载

  • 作用:可以输出自定义数据类型

  • 重载左移运算符配合友元可以实现输出自定义数据类型

cpp 复制代码
#include <iostream>

using namespace std;

class Person{
	friend ostream& operator<<(ostream& cout, Person p);
public:
	Person(int a, int b){
		this->a = a;
		this->b = b;
	}
	// 成员函数重载左移运算符的本质是p<<cout
	// 在C++中一般不适用成员函数重载左移运算符,因为无法实现cout<<p的格式
	// operator<<(cout) {}
private:
	int a;
	int b;
};

// ostream& 返回cout这样可以在链式使用时继续追加
// 本质:operator<<(cout, p),简化为cout<<p
ostream& operator<<(ostream& cout, Person& p) {
	cout << "a= " << p.a <<" b= " << p.b;
	return cout;
}

void test(){
	Person p(1,1);
	cout << p << endl;
}

int main(){
	test();
	return 0;
}

递增运算符重载

  • 通过重载自增运算符,实现自己的整形数据
cpp 复制代码
#include <iostream>

using namespace std;

class MyInt{
	friend ostream& operator<<(ostream& cout, MyInt i);
public:
	// 重载前置++运算符,返回引用为了一直对一个数据进行递增操作
	MyInt& operator++(){
		num++;
		return *this;
	}
	// 重载后置++运算符
	// void operator++(int) int代表占位参数,可以用于区分前置和后置递增
	MyInt operator++(int){
		MyInt temp = *this;
		num++;
		return temp;
	}
private:
	int num;
};

ostream& operator<<(ostream& cout, MyInt i){
	cout << i.num;
	return cout;
}

void test(){
	MyInt myint;
	cout << ++(++myint) << endl;
	MyInt myint1;
	cout << (myint++)++ << endl;
}

int main(){
	test();
	return 0;
}

赋值运算符重载

cpp 复制代码
#include <iostream>

using namespace std;

class Person{
public:
	Person(int age) {
		this->age=new int(age);
	}
	Person& operator=(const Person& p) {
		// 编译器提供的是浅拷贝
		// age=p.age;
		// 先判断是否有属性在堆区,如果有先释放,然后在深拷贝
		if (age != NULL) {
			delete age;
			age=NULL;
		}
		// 深拷贝
		age=new int(*p.age);
		return *this;
	}
	~Person(){
		if (age == NULL) {
			return;
		}
		delete age;
		age=NULL;
	}
	int* age;
};

void test(){
	Person p1(18);
	Person p2(20);
	Person p3(30);
	p3=p2=p1;
	cout << *p1.age << endl;
	cout << *p2.age << endl;
	cout << *p3.age << endl;
}

int main(){
	test();
	return 0;
}

关系运算符重载

cpp 复制代码
#include <iostream>

using namespace std;

class Person{
	friend ostream& operator<<(ostream& cout, Person& p);
public:
	Person(int age) {
		this->age=age;
	}
	bool operator==(const Person& p) {
		return age==p.age;
	}

	bool operator!=(const Person& p) {
		return age!=p.age;
	}
	bool operator>(const Person& p) {
		return age>p.age;
	}
	bool operator>=(const Person& p) {
                return age>=p.age;
        }
	bool operator<(const Person& p) {
                return age<p.age;
        }
	bool operator<=(const Person& p) {
                return age<=p.age;
        }
private:
	int age;
};

ostream& operator<<(ostream& cout, Person& p){
	cout << p.age << endl;
	return cout;
}

void test(){
	Person p1(18);
	Person p2(20);
	cout << (p1== p2) << endl;
	cout << (p1!= p2) << endl;
	cout << (p1>= p2) << endl;
	cout << (p1> p2) << endl;
	cout << (p1<= p2) << endl;
	cout << (p1< p2) << endl;
}

int main(){
	test();
	return 0;
}

函数调用运算符重载

  • 由于重载后的使用方式很像函数调用,因此也称为仿函数

  • 仿函数没有固定写法,非常灵活

cpp 复制代码
#include <iostream>

using namespace std;

class Person{
public:
        // 打印类仿函数
        void operator()(string text) {
                cout << text << endl;
        }
};

class MyAdd{
public:
        // 加法类仿函数
        int operator()(int num1, int num2) {
                return num1+num2;
        }
};
 
void test(){
        Person p;
        // 由于使用起来非常类似于函数调用,因此也称为仿函数
        p("123");
}

void test1(){
        MyAdd myAdd;
        cout << myAdd(1,2) << endl;
        // 使用匿名函数调用
        cout <<MyAdd()(100,10) << endl;
}

int main(){
        test();
        test1();
        return 0;
}
相关推荐
程序喵大人4 小时前
【C++进阶】STL容器与迭代器 - 01 STL 容器先解决元素放在哪里
开发语言·c++·stl
cui_ruicheng5 小时前
Python从入门到实战(十六):多进程编程
开发语言·python
wdfk_prog6 小时前
嵌入式面试真题第 15 题:不可恢复异常后的通用崩溃快照、调用栈保存与离线分析架构
linux·开发语言·面试·架构
晴空了无痕6 小时前
从 Go 基础到 K8s:一条可落地的 Go 服务端成长路线
开发语言·后端·golang·kubernetes
神明不懂浪漫6 小时前
【第五章】Java中的继承与多态
java·开发语言
神州世通7 小时前
解密企业通信安全防线:Avaya Aura 三层安全架构深度解析
开发语言·php
AC赳赳老秦8 小时前
企业工商公开信息采集分析:OpenClaw 批量查询企业工商信息,生成企业画像报告
大数据·开发语言·python·自动化·php·deepseek·openclaw
qq_2518364578 小时前
基于java Web 动漫视频网站毕业论文
java·开发语言·前端
野生风长8 小时前
C++入门基础:从命名空间到引用与指针的全面解析
开发语言·c++
FoldWinCard9 小时前
D6 Python 基础语法 --- 保留关键字
开发语言·python