【C++第二阶段】运算符重载-【+】【cout】【++|--】

你好你好!
以下内容仅为当前认识,可能有不足之处,欢迎讨论!


文章目录

  • 运算符重载
    • 加法运算符重载
    • 重载左移运算符
    • 递增|减运算符重载


运算符重载

加法运算符重载

What

普通的加减乘除,只能应付C++中已给定的数据类型的运算,对其重载,使得满足多种多样的运算。

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

注意

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

②不要滥用运算符重载。

对于①,基本的运算符运算不改变,int+int = int , float + float = float.

对于②,重写相加,就写相加,名副其实。如果重写了加法运算符,里面却写➖或者×÷,代码可读性会变差。

代码

成员函数重载加法运算符

#include
#include
using namespace std;
void test_0208_0();

class Person {
public:
	float person_height;
	int person_weight;
	Person operator+(Person& person);//成员函数运算符重载
};

Person Person::operator+(Person& person) {
	Person temp;
	temp.person_height = this->person_height + person.person_height;
	temp.person_weight = this->person_weight + person.person_weight;
	return temp;
}

void test_0208_0() {
	Person per, son , person_sum;
	per.person_weight = 70;
	per.person_height = 1.83;

	son.person_weight = 60;
	son.person_height = 1.83;

	person_sum = per + son;
	//成员函数重载加法运算符相当于:
	//person_sum = per.operator+(son);

	cout << "person sum 总身高为:" << person_sum.person_height << "." << endl;
	cout << "person sum 总体重为:" << person_sum.person_weight << "." << endl;

}


int main() {
	cout << "hello world !" << endl;
	test_0208_0();
    
    system("pause");
    return 0;
}

运行结果

【C++第二阶段】运算符重载-【+】【cout】【++|--】_第1张图片

可以看到,将两人的身高和体重在加法运算符重载之后进行了求和。

全局函数重载加法运算符

#include
#include
using namespace std;
void test_0208_0();
void test_0208_1();
void test_0208_2();

class Person {
public:
	float person_height;
	int person_weight;
	Person operator+(Person& person);//成员函数运算符重载
};

Person operator+(Person& per, Person& son) {
	Person temp;
	temp.person_height = per.person_height + son.person_height;
	temp.person_weight = per.person_weight + son.person_weight;
	return temp;
}

void test_0208_0() {
	Person per, son , person_sum;
	per.person_weight = 70;
	per.person_height = 1.83;

	son.person_weight = 60;
	son.person_height = 1.83;

	person_sum = per + son;

	//全局成员函数重载加法运算符相当于:
	//person_sum = operator+(per , son);

	cout << "person sum 总身高为:" << person_sum.person_height << "." << endl;
	cout << "person sum 总体重为:" << person_sum.person_weight << "." << endl;

}

int main() {
	cout << "hello world !" << endl;
	test_0208_0();
    system("pause");
    return 0;
}

运行结果

【C++第二阶段】运算符重载-【+】【cout】【++|--】_第2张图片

重载左移运算符

场景:

想要cout直接输出类里面的各种属性,简单地使用``cout<会报错。需要重写<<`运算符。

How

考虑到加法运算符的重载,使用成员函数重载左移运算符。

但此时,有两个问题:①函数返回值是什么数据类型?②如何调用?

回答问题①

通过点击cout右键后,选择转到定义。

【C++第二阶段】运算符重载-【+】【cout】【++|--】_第3张图片

接着出现:

【C++第二阶段】运算符重载-【+】【cout】【++|--】_第4张图片

可以看到,cout属于的类是ostream输出流对象。

所以,如果想链式调用函数,可以将返回值设置为ostream。同时,只能用引用方式传递,因为全局只能有一个。

成员函数重载左移运算符:

#include
#include
using namespace std;
void test_0208_1();

class Person {
private :
	int weight;
	double height;
public:
	Person(int weight, double height);
	void operator<<(ostream& cout);
};

Person::Person(int weight, double height) {
	this->weight = weight;
	this->height = height;
}

void Person::operator<<(ostream &cout) {
	cout << "person 的身高为:" << this->height << "." << endl;
	cout << "person 的体重为:" << this->weight << "." << endl;

}

void test_0208_1() {
	int weight = 70;
	double height = 1.85;
	Person person(weight, height);
	person << cout;
	//等价于
	//person.operator<<(cout);
}


int main() {
	cout << "hello world !" << endl;
	test_0208_1();
	system("pause");
	return 0;
	}
	

运行结果为:

【C++第二阶段】运算符重载-【+】【cout】【++|--】_第5张图片

但是不想要person<,或者person.operator<<(cout);这样的写作方式,而是要重载后的输出方式cout<

如果现在加上<则后面会报错。

【C++第二阶段】运算符重载-【+】【cout】【++|--】_第6张图片

image-20240208172322256

这个方式实际上是链式调用函数出错出现的问题,可以更改返回值为对应的ostream &引用来解决。

比如,以上代码中的成员函数改为:

class Person {

private :
	int weight;
	double height;
public:
	Person(int weight, double height);
    //返回值由void 改为ostream &
	ostream& operator<<(ostream& cout);
};

Person::Person(int weight, double height) {
	this->weight = weight;
	this->height = height;
}

//返回值由void 改为ostream
ostream& Person::operator<<(ostream &cout) {
	cout << "person 的身高为:" << this->height << "." << endl;
	cout << "person 的体重为:" << this->weight << "." << endl;
	return cout;
}


void test_0208_1() {
	int weight = 70;
	double height = 1.85;
	Person person(weight, height);
	person << cout<<endl;//添加endl后不会报错
	//等价于
	//person.operator<<(cout);
}

运行结果为

【C++第二阶段】运算符重载-【+】【cout】【++|--】_第7张图片

但仍没有解决想要使用cout<进行输出的问题。

原因在于,如果用成员函数重载,则person只能出现在左侧,cout出现在右侧。所以,更换为使用全局函数。

全局函数重载左移运算符

#include
#include
using namespace std;
void test_0208_0();
void test_0208_1();
void test_0208_2();

class Person {
    //要注意添加全局函数为类的友元,否则私有成员属性无法访问。
	friend ostream& operator<<(ostream& out, Person &person);
private :
	int weight;
	double height;
public:
	Person(int weight, double height);
	//void operator<<(ostream& cout);
};

Person::Person(int weight, double height) {
	this->weight = weight;
	this->height = height;
}

ostream& operator<<(ostream& out,Person& person) {
    //这里的out是引用,就是别名。
	out << "person 的身高为:" << person.height << "." << endl;
	out << "person 的身高为:" << person.weight << "." << endl;
	return out;
}

void test_0208_1() {
	int weight = 70;
	double height = 1.85;
	Person person(weight, height);
	cout << person << endl;
	//全局函数重载等价于
	//operator<<(cout, person);
}

int main() {
	cout << "hello world !" << endl;
	test_0208_1();
	system("pause");
    return 0;
}

operator<<(cout,person)运行结果:

【C++第二阶段】运算符重载-【+】【cout】【++|--】_第8张图片

递增|减运算符重载

目的

想要达到一个自定义的整数类实现前置递增或后置递增的操作。

How

分为前置递增运算符和后置递增运算符。

对于前置递增运算符,返回值需要是MyInt类型的,因为cout已经重写,所以最好是这种类型。

返回值是指针,因为是对于当前的类进行的加减操作。

对于后置递增运算符,需要在参数中写入占位符,编译器明白这是后置运算符。

#include
#include
using namespace std;
void test_0208_1();
void test_0208_2();
void test_0208_3();
void test_0208_4();
void test_0208_5();

class MyInt {
	friend ostream& operator<<(ostream& print, MyInt my_int);

private:
	int num;

public:
	MyInt() {
		num = 0;
	}
	MyInt(int number) {
		num = number;
	}

	//成员函数-前置递增函数
	//返回值为什么是数字,因为想要它实现前置递增的功能,让cout输出,但是cout不知道怎么输出void类型的变量
	//所以需要返回值
	//需要返回自身,this是指针,解引用之后才是自身。
	//至于返回值,则是一个引用


	//MyInt& operater++() {
		//this->num++;
		//return *this;
	//}

	//若返回值,则以下为返回值的测试案例
	MyInt& operator++() {
		this->num++;
		return *this;
	}


	//成员函数-后置递增函数
	MyInt& operator++(int) {
		static MyInt temp = *this;
		this->num++;
		return temp;
	}

	MyInt& operator--() {
		--this->num;
		return *this;
	}

	MyInt& operator--(int) {
		static MyInt temp = *this;
		this->num--;
		return temp;
	}
	
	
};

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


void test_0208_2() {
	cout << "==========test_0208_2()==========" << endl;
	MyInt my_int(20);
	cout <<"my_int \t==>" << my_int << endl;
	cout << "========\t" << endl;
	cout << "++my_int ==>" << ++my_int << endl;
	cout << "my_int \t==>" << my_int << endl;
	//使用返回值的前置递增函数,两次递增后,新的值为新的随机值,而不是my_int
	//对于my_int为什么是11,是因为只有第一个作为存储值留下来了
	cout << "========\t" << endl;
	cout << "++(++my_int)==>" << ++(++my_int) << endl;
	cout <<"my_int \t==>" << my_int << endl;
	cout << "==========test_0208_2()==========\n" << endl;

}

void test_0208_3() {
	cout << "==========test_0208_3()==========" << endl;
	MyInt my_int = 30;
	cout << "原始的my_int = " << my_int << "." << endl;
	cout << "my_int ++ 后,my_int = " << my_int++ << "." << endl;
	cout << "现在的my_int = " << my_int << "." << endl;
	cout << "==========test_0208_3()==========\n" << endl;
}


void test_0208_4() {
	cout << "==========test_0208_4()==========" << endl;
	MyInt my_int(40);
	cout << "my_int \t==>" << my_int << endl;
	cout << "========\t" << endl;
	cout << "--my_int ==>" << --my_int << endl;
	cout << "my_int \t==>" << my_int << endl;
	//使用返回值的前置递增函数,两次递增后,新的值为新的随机值,而不是my_int
	//对于my_int为什么是11,是因为只有第一个作为存储值留下来了
	cout << "========\t" << endl;
	cout << "--(--my_int)==>" << --(--my_int) << endl;
	cout << "my_int \t==>" << my_int << endl;
	cout << "==========test_0208_4()==========\n" << endl;

}

void test_0208_5() {
	cout << "==========test_0208_5()==========" << endl;
	MyInt my_int = 50;
	cout << "原始的my_int = " << my_int << "." << endl;
	cout << "my_int -- 后,my_int = " << my_int-- << "." << endl;
	cout << "现在的my_int = " << my_int << "." << endl;
	cout << "==========test_0208_5()==========\n" << endl;
}

int main() {
	cout << "hello world !" << endl;
	test_0208_5();
	test_0208_4();
	test_0208_3();
	test_0208_2();
    system("pause");
    return 0;
}

运行结果

【C++第二阶段】运算符重载-【+】【cout】【++|--】_第9张图片


以上是我的学习笔记,希望对你有所帮助!
如有不当之处欢迎指出!谢谢!

学吧,学无止境,太深了

你可能感兴趣的:(C++学习与回顾,c++,java,算法)