【黑马程序员】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;
}
相关推荐
獨枭2 小时前
CMake 构建项目并整理头文件和库文件
c++·github·cmake
西猫雷婶2 小时前
python学opencv|读取图像(十九)使用cv2.rectangle()绘制矩形
开发语言·python·opencv
liuxin334455662 小时前
学籍管理系统:实现教育管理现代化
java·开发语言·前端·数据库·安全
码农W3 小时前
QT--静态插件、动态插件
开发语言·qt
ke_wu3 小时前
结构型设计模式
开发语言·设计模式·组合模式·简单工厂模式·工厂方法模式·抽象工厂模式·装饰器模式
code04号3 小时前
python脚本:批量提取excel数据
开发语言·python·excel
小王爱吃月亮糖3 小时前
C++的23种设计模式
开发语言·c++·qt·算法·设计模式·ecmascript
hakesashou3 小时前
python如何打乱list
开发语言·python
网络风云4 小时前
【魅力golang】之-反射
开发语言·后端·golang
Want5954 小时前
Java圣诞树
开发语言·python·信息可视化