zoukankan      html  css  js  c++  java
  • 学习:类和对象——运算符重载

    什么是运算符重载?

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

    对于个人而言,学到这里的感受就是,多了一种能够自定义方式来进行运算的方式吧,通过类似语法糖的效果operator+来自动实现相应的操作


    +号运算符重载:

    作用:实现两个自定义数据类型相加的运算

    在+号运算符重载里面,我们可以通过两种方式来定义,一种是成员函数来实现,还有一种全局函数来实现

    同样的调用方法也有两种,以下代码有体现

    示例代码:

    #include<iostream>
    #include<string>
    
    using namespace std;
    
    class Person{
    public:
    
    	//成员函数实现 + 号运算符重载
    	//Person operator+(Person& p1) {
    	//	Person temp;
    	//	temp.age = this->age + p1.age;
    	//	return temp;
    	//}
    
    public:
    	int age;
    };
    
    //全局函数 实现+号运算符重载
    Person operator+(Person& p1, int val) {
    	Person temp;
    	temp.age = p1.age + val;
    	return temp;
    }
    
    int main() {
    	Person p1;
    	p1.age = 20;
    	//Person p2 = p1.operator+(p1); //调用方式有两种,这是第一种
    	Person p2 = p1 + 10;//这是第二种调用方式
    	cout << p2.age << endl;
    	system("pause");
    	return 0;
    }
    

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

    总结2:不要滥用运算符重载


    左移运算符重载

    通过左移运算符重载,我们可以实现输出自定义数据类型,比如 cout << 对象 << endl,实际输出的是 cout << 对象.a << endl

    #include<iostream>
    #include<string>
    
    using namespace std;
    
    class Person {
    	friend ostream& operator<<(ostream& cout, Person& p); //因为a,b是私有成员变量,所以我们利用friend友元进行修饰,让其能够访问到我们的私有变量
    
    public:
    	Person(int a, int b) {
    		this->a = a;
    		this->b = b;
    	}
    
    	//void operator<<(cout) {} //在类中定义的话无法实现 cout << p这种形式到时候调用的时候只能是p.operator<<(p),简化版只能是 p << cout,所以我们只在全局区定义函数
    
    private:
    	int a;
    	int b;
    };
    
    ostream& operator<<(ostream& cout,Person& p) {  // 都不需要生成一个新的内存空间,所以都进行传参引用
    	cout << p.a << "," << p.b << endl;
    	return cout; // 这里返回的是ostream类型 是为了进行后面 << 继续拼接的输出,链式操作
    }
    
    
    
    int main() {
    	Person p1(1, 2);
    	cout << p1 << "hello world " <<endl;  //通过p1 直接可以输出对象p1的成员变量
    	system("pause");
    	return 0;
    
    }
    

    递减运算符重载:

    作用: 通过重载递减运算符,实现自己的整型数据

    #include<iostream>
    #include<string>
    
    using namespace std;
    
    class Num {
    
    	//创建友元函数,因为这里a是私有变量
    	friend ostream & operator<<(ostream& cout, Num n);
    
    public:
    	Num(int a) {
    		this->a = a;
    	}
    
    	Num & operator--() {// 定义前置--运算符重载
    		a--;
    		return *this;
    		
    	}
    
    	Num operator--(int) { //定义后置--运算符重载 这时候int这种占位参数就体现出来了,区别前置还是后置不要问为什么,因为有个傲娇的编译器
    		Num temp = *this;
    		this->a--;
    		return temp;
    	}
    
    private:
    	int a;
    };
    
    //重载一个左移运算符
    ostream & operator<<(ostream& cout, Num n) {
    	cout << n.a;
    	return cout;
    }
    
    int main() {
    	Num n1(1);
    	cout << --n1 << endl;
    	cout << n1-- << endl;
    	system("pause");
    	return 0;
    	
    }
    

    赋值运算符重载:

    c++编译器至少给一个类添加4个函数

    1、默认构造函数(无参,函数体为空)

    2、默认析构函数(无参,函数体为空)

    3、默认拷贝构造函数,对属性进行值拷贝

    4、赋值运算符 operator=, 对属性进行值拷贝

    如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题

    #include<iostream>
    #include<string>
    
    using namespace std;
    
    class Person {
    public:
    	Person(int height) {
    		this->height= new int(height);
    	}
    
    	Person & operator=(Person & p) {
    		if (this->height != NULL) {
    			delete this->height;
    			this->height = NULL;
    		}
    		this->height = new int(*p.height);
    		return *this;
    	}
    
    	~Person() {
    		if (this->height != NULL) {
    			delete this->height;
    			this->height = NULL;
    		}
    	}
    
    public:
    	int * height;
    };
    
    int main() {
    	Person p1(180);
    	Person p2(170);
    	p2 = p1;
    
    	cout << *p1.height << endl;
    	cout << *p2.height << endl;
    	system("pause");
    	return 0;
    	
    }
    

    关系运算符重载:

    作用:重载关系运算符,可以让两个自定义类型对象进行对比操作

    还是一样的,就是返回个类型应该来说是个布尔值,因为是==比较

    #include<iostream>
    #include<string>
    
    using namespace std;
    
    class Person {
    public:
    	Person(int age) {
    		this->age = age;
    	
    	}
    
    	bool operator==(Person& p) {
    		if (this->age == p.age) {
    			return true;
    		}
    		else {
    			return false;
    		}
    	}
    
    	bool operator!=(Person& p) {
    		if (this->age == p.age) {
    			return false;
    		}
    		else {
    			return true;
    		}
    	}
    public:
    	string name;
    	int age;
    };
    
    int main() {
    	Person p1(18);
    	Person p2(18);
    	if (p1 == p2) {
    		cout << "相等" << endl;
    	}else{
    		cout << "不相等" << endl;
    	}
    
    	system("pause");
    	return 0;
    	
    }
    

    函数调用运算符重载:

    1、函数调用运算符 () 也可以重载

    2、由于重载后使用的方式非常像函数的调用,因此称为仿函数,仿函数没有固定写法,非常灵活

    自己总结下这个知识点:

    1、第一点是函数调用运算符重载,也就是跟之前的一样加个()就好了
    2、第二点是匿名对象类,也可以我们后面不需要再继续用到,所以就不需要进行储存操作,一次性调用就可以了

    体现代码:

    #include<iostream>
    #include<string>
    
    using namespace std;
    
    class Printer{
    public:
    	void operator()(string name) {
    		cout << name << endl;
    	}
    };
    
    
    int main() {
    	Printer p1;
    	p1("adexx"); //一种方式来调用
    
    	Printer()("adexx");//使用匿名类来进行调用
    	system("pause");
    	return 0;
    	
    }
    
  • 相关阅读:
    洛谷 P2807 三角形计数
    洛谷 P1727 计算π
    洛谷 P1595 信封问题
    洛谷 P3131 [USACO16JAN]子共七Subsequences Summing to Sevens
    3.1、spark集群运行应用
    移动端自适应
    【Flex布局】
    【pm2】
    【安全】
    【Bower】
  • 原文地址:https://www.cnblogs.com/zpchcbd/p/11865686.html
Copyright © 2011-2022 走看看