day15_运算符重载(operator overload)

运算符重载 (operator overload)

运算符重载(操作符重载):可以为运算符增加一些新的功能

// operator overload

//class Point {
//	friend Point operator+(const Point &, const Point &);
//	int m_x;
//	int m_y;
//public:
//	Point(int x, int y) :m_x(x), m_y(y) { }
//	void display() {
//		cout << "(" << this->m_x << ", " << this->m_y << ")" << endl;
//	}
//};
//
//// 运算符(操作符)重载
//Point operator+(const Point &p1, const Point &p2) {
//	return Point(p1.m_x + p2.m_x, p1.m_y + p2.m_y);
//}


int main() {
	Point p0(5, 10);
	Point p1(30, 70);
	Point p2(10, 40);
	Point p3 = p1++ - p2;

	// Java.toString   OC.description
	cout << p0 << p1 << p2 << p3 << endl;

	// p0 << 1 << 2 << 3;

	// 运算符重载:最好保留运算符以前的语义

	// p1.display();
	// p3.display();

	/*int a = 10;
	int b = 0;
	b = a++ + 8;
	b = ++a + 8;
	cout << a << endl;*/

	// (a++) = 40;
	// (++a) = 50;

	/*
	int a = 10;
	a++;
	++a;
	(a++) = 30;
	(++a) = 40;
	*/

	// int a = 10;
	// int c = a++ + ++a + a++ + ++a;

	/*p1++;
	++p1;
	p1--;
	--p1;*/

	(-(-p1));

	// cout << (p1 != p2) << endl;

	/*Point p3 = p0 + p1 + p2;
	p3.display();

	Point p4 = p1 - p2;
	p4.display();

	(p1 += p2) = Point(100, 200);
	p1.display();*/


	/*int a = 10;
	int b = 20;
	(a += b) = 50;
	cout << a << endl;*/

	// Point p3 = p1.operator+(p2);
	// Point p3 = operator+(p1, p2);

	getchar();
	return 0;
}

#pragma once
#include <iostream>
using namespace std;

class Point {
	friend ostream &operator<<(ostream &, const Point &);
	int m_x;
	int m_y;
public:
	Point(int x, int y);
	// 运算符(操作符)重载
	Point operator+(const Point &point) const;
	Point operator-(const Point &point) const;
	const Point operator-() const;
	Point &operator+=(const Point &point);
	Point &operator-=(const Point &point);
	bool operator==(const Point &point);
	bool operator!=(const Point &point);
	// 前++
	Point &operator++();
	// 后++
	const Point operator++(int);
};

#include "Point.h"

Point::Point(int x, int y) :m_x(x), m_y(y) { }

// 运算符(操作符)重载
Point Point::operator+(const Point &point) const {
	return Point(this->m_x + point.m_x, this->m_y + point.m_y);
}

Point Point::operator-(const Point &point) const {
	return Point(this->m_x - point.m_x, this->m_y - point.m_y);
}

const Point Point::operator-() const {
	return Point(-this->m_x, -this->m_y);
}

Point &Point::operator+=(const Point &point) {
	this->m_x += point.m_x;
	this->m_y += point.m_y;
	return *this;
}

Point &Point::operator-=(const Point &point) {
	this->m_x -= point.m_x;
	this->m_y -= point.m_y;
	return *this;
}

bool Point::operator==(const Point &point) {
	// 1 YES true
	// 0 NO false
	/*if (this->m_x == point.m_x && this->m_y == point.m_y) {
		return 1;
	}
	else {
		return 0;
	}*/
	return (this->m_x == point.m_x) && (this->m_y == point.m_y);
}

bool Point::operator!=(const Point &point) {
	return (this->m_x != point.m_x) || (this->m_y != point.m_y);
}

// 前++
Point &Point::operator++() {
	this->m_x++;
	this->m_y++;
	return *this;
}

// 后++
const Point Point::operator++(int) {
	Point point(this->m_x, this->m_y);
	this->m_x++;
	this->m_y++;
	return point;
}

ostream &operator<<(ostream &cout, const Point &point) {
	return cout << "(" << point.m_x << ", " << point.m_y << ")";
}



  • 全局函数、成员函数都支持运算符重载

String

#pragma once
#include <iostream>
using namespace std;

class String {
	friend ostream &operator<<(ostream &, const String &);
public:
	String(const char *cstring);
	String(const String &string);
	~String();
	String &operator=(const char *cstring);
	String &operator=(const String &string);
private:
	char *m_cstring;
	String &assign(const char *cstring);
};



#include "String.h"

String::String(const char *cstring) {
	/*if (!cstring) return;
	cout << "String(const char *) - new[] - " << cstring << endl;

	this->m_cstring = new char[strlen(cstring) + 1] {};
	strcpy(this->m_cstring, cstring);*/
	assign(cstring);
} 

String::String(const String &string) {
	// *this = string.m_cstring;
	// (*this).operator=(string.m_cstring);
	assign(string.m_cstring);
}

String::~String() {
	// if (!this->m_cstring) return;
	// cout << "~String() - delete[] - " << this->m_cstring << endl;
	//delete[] this->m_cstring;
	//this->m_cstring = NULL;

	// operator=(NULL);
	// *this = NULL;
	/*(*this).operator=(NULL);
	this->operator=(NULL);
	operator=(NULL);*/
	assign(NULL);
}

String &String::operator=(const char *cstring) {
	return assign(cstring);
}

String &String::operator=(const String &string) {
	// return operator=(string.m_cstring);
	// return *this = string.m_cstring;
	return assign(string.m_cstring);
}

String &String::assign(const char *cstring) {
	// 指向一样的堆空间
	if (this->m_cstring == cstring) return *this;

	// 释放旧的字符串
	if (this->m_cstring) {
		cout << "delete[] - " << this->m_cstring << endl;

		delete[] this->m_cstring;
		this->m_cstring = NULL;
	}

	// 指向新的字符串
	if (cstring) {
		cout << "new[] - " << cstring << endl;

		this->m_cstring = new char[strlen(cstring) + 1]{};
		strcpy(this->m_cstring, cstring);
	}

	return *this;
}

ostream &operator<<(ostream &cout, const String &string) {
	if (!string.m_cstring) return cout;
	return cout << string.m_cstring;
}

#pragma once
#include <iostream>
using namespace std;

class String {
	friend ostream &operator<<(ostream &, const String &);
public:
	String(const char *cstring = "");
	String(const String &string);
	~String();
	String &operator=(const char *cstring);
	String &operator=(const String &string);
	String operator+(const char *cstring);
	String operator+(const String &string);
	String &operator+=(const char *cstring);
	String &operator+=(const String &string);
	bool operator>(const char *cstring);
	bool operator>(const String &string);
	char operator[](int index);
private:
	char *m_cstring = NULL;
	String &assign(const char *cstring);
	char *join(const char *cstring1, const char *cstring2);
};

#include "String.h"

String::String(const char *cstring) {
	assign(cstring);
}

String::String(const String &string) {
	assign(string.m_cstring);
}

String::~String() {
	assign(NULL);
}

String &String::operator=(const char *cstring) {
	return assign(cstring);
}

String &String::operator=(const String &string) {
	return assign(string.m_cstring);
}

String String::operator+(const char *cstring) {
	String str;
	char *newCString = join(this->m_cstring, cstring);
	if (newCString) {
		// 释放旧的堆空间
		str.assign(NULL);
		// 直接指向新开辟的堆空间
		str.m_cstring = newCString;
	}
	return str;
}

String String::operator+(const String &string) {
	return operator+(string.m_cstring);
}

String &String::operator+=(const char *cstring) {
	char *newCString = join(this->m_cstring, cstring);
	if (newCString) {
		this->assign(NULL);
		this->m_cstring = newCString;
	}
	return *this;
}

String &String::operator+=(const String &string) {
	return operator+=(string.m_cstring);
}

bool String::operator>(const char *cstring) {
	if (!this->m_cstring || !cstring) return 0;
	return strcmp(this->m_cstring, cstring) > 0;
}

bool String::operator>(const String &string) {
	return operator>(string.m_cstring);
}

char String::operator[](int index) {
	if (!this->m_cstring || index < 0) return '\0';
	if (index >= strlen(this->m_cstring)) return '\0';
	return this->m_cstring[index];
}

char *String::join(const char *cstring1, const char *cstring2) {
	if (!cstring1 || !cstring2) return NULL;

	char *newCString = new char[strlen(cstring1) + strlen(cstring2) + 1] {};
	strcat(newCString, cstring1);
	strcat(newCString, cstring2);

	cout << "new[] - " << newCString << endl;
	return newCString;
}

String &String::assign(const char *cstring) {
	// 指向一样的堆空间
	if (this->m_cstring == cstring) return *this;

	// 释放旧的字符串
	if (this->m_cstring) {
		cout << "delete[] - " << this->m_cstring << endl;

		delete[] this->m_cstring;
		this->m_cstring = NULL;
	}

	// 指向新的字符串
	if (cstring) {
		cout << "new[] - " << cstring << endl;

		this->m_cstring = new char[strlen(cstring) + 1]{};
		strcpy(this->m_cstring, cstring);
	}

	return *this;
}

ostream &operator<<(ostream &cout, const String &string) {
	if (!string.m_cstring) return cout;
	return cout << string.m_cstring;
}

单例模式补充

#include <iostream>
using namespace std;
class Rocket {
public:
	static Rocket * sharedRocket() {
		if (ms_rocket) return ms_rocket;
		return ms_rocket = new Rocket();
	}
	static void deleteRocket() {
		if (!ms_rocket) return;

		delete ms_rocket;
		ms_rocket = NULL;
	}
private:
	static Rocket *ms_rocket;
	Rocket() { }
	Rocket(const Rocket &rocket) { }
	void operator=(const Rocket &rocket) { }
};

Rocket *Rocket::ms_rocket = NULL;

/*
单例需要禁止掉:拷贝行为、赋值行为
*/

int main() {

	Rocket *p1 = Rocket::sharedRocket();
	Rocket *p2 = Rocket::sharedRocket();

	getchar();
	return 0;
}

运算符重载注意点

  • 有些运算符不可以被重载,比如
    • 对象成员访问运算符:.
    • 域运算符:::
    • 三目运算符:?:
    • sizeof
  • 有些运算符只能重载为成员函数,比如
    • 赋值运算符:=
    • 下标运算符:[ ]
    • 函数运算符:( )
    • 指针访问成员:->
posted @ 2021-04-23 22:12  AAAAAAAAA123123  阅读(111)  评论(0编辑  收藏  举报