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

文章目录

  • 运算符重载
    • 加号运算符重载
      • 成员函数实现运算符重载
      • 全局函数实现运算符重载
      • 全局函数实现函数重载
    • 左移运算符重载
    • 递增运算符重载
    • 赋值运算符重载
    • 关系运算符重载
    • 函数调用运算符重载

运算符重载

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

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

  • 不要滥用运算符重载

加号运算符重载

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

成员函数实现运算符重载

  • 成员函数实现运算符重载的本质 p2.operator(p1)
#include 

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)
#include 

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;
}

全局函数实现函数重载

  • 通过函数重载实现不同类型的加法运算
#include 

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;
}

左移运算符重载

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

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

#include 

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<
	// 在C++中一般不适用成员函数重载左移运算符,因为无法实现cout<
	// operator<<(cout) {}
private:
	int a;
	int b;
};

// ostream& 返回cout这样可以在链式使用时继续追加
// 本质:operator<<(cout, p),简化为cout<
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;
}

递增运算符重载

  • 通过重载自增运算符,实现自己的整形数据
#include 

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;
}

赋值运算符重载

#include 

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;
}

关系运算符重载

#include 

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;
}

函数调用运算符重载

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

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

#include 

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;
}

你可能感兴趣的:(#,C++笔记,c++,开发语言)