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
- 有些运算符只能重载为成员函数,比如
- 赋值运算符:=
- 下标运算符:[ ]
- 函数运算符:( )
- 指针访问成员:->