文章目录
C++中的运算符重载(operator overload)
- 运算符重载(操作符重载):可以为运算符增加一些新的功能;
1. +
方法一:
class Point {
public:
int m_x;
int m_y;
Point(int x, int y) :m_x(x), m_y(y) { }
Point(const Point &point) :m_x(point.m_x), m_y(point.m_y) { } //const型参数可以接受const和非const实参,&可以避免中间对象的生成
void display() {
cout << "x = " << this->m_x << ", y = " << this->m_y << endl;
}
};
Point operator+(const Point &p1, const Point &p2) { //const型参数可以接受const和非const实参,&可以避免中间对象的生成
return Point(p1.m_x + p2.m_x, p1.m_y + p2.m_y);
}
方法二(重载函数写到类里面)
class Point {
public:
int m_x;
int m_y;
Point(int x, int y) :m_x(x), m_y(y) { }
Point(const Point &point) :m_x(point.m_x), m_y(point.m_y) { } //const型参数可以接受const和非const实参,&可以避免中间对象的生成
const Point operator+(const Point &point) const{
return Point(m_x + point.m_x, m_y + point.m_y); //因为const对象不能调用非const函数,所以应用常量函数;而且不允许a + b = 10类赋值,所以同理应返回const对象
}
void display() {
cout << "x = " << this->m_x << ", y = " << this->m_y << endl;
}
};
- 全局函数、成员函数都支持运算符重载。
2. -
class Point {
public:
int m_x;
int m_y;
Point(int x, int y) :m_x(x), m_y(y) { }
Point(const Point &point) :m_x(point.m_x), m_y(point.m_y) { } //const型参数可以接受const和非const实参,&可以避免中间对象的生成
const Point operator+(const Point &point) const{
return Point(m_x - point.m_x, m_y - point.m_y); //因为const对象不能调用非const函数,所以应用常量函数;而且不允许a - b = 10类赋值,所以同理应返回const对象
}
void display() {
cout << "x = " << this->m_x << ", y = " << this->m_y << endl;
}
};
3. += 和 -=
+=:
class Point {
public:
int m_x;
int m_y;
Point(int x, int y) :m_x(x), m_y(y) { }
Point(const Point &point) :m_x(point.m_x), m_y(point.m_y) { } //const型参数可以接受const和非const实参,&可以避免中间对象的生成
Point &operator+=(const Point &point) { //返回引用型对象,可以避免中间对象;
C++允许 a+=b = 10,所以不用返回常对象
m_x += point.m_x;
m_y += point.m_y;
return *this;
}
void display() {
cout << "x = " << this->m_x << ", y = " << this->m_y << endl;
}
-=:
class Point {
public:
int m_x;
int m_y;
Point(int x, int y) :m_x(x), m_y(y) { }
Point(const Point &point) :m_x(point.m_x), m_y(point.m_y) { } //const型参数可以接受const和非const实参,&可以避免中间对象的生成
Point &operator-=(const Point &point) { //返回引用型对象,可以避免中间对象;
C++允许 a+=b = 10,所以不用返回常对象
m_x -= point.m_x;
m_y -= point.m_y;
return *this;
}
void display() {
cout << "x = " << this->m_x << ", y = " << this->m_y << endl;
}
4. ==和!=
==:
class Point {
int m_x;
int m_y;
public:
Point(int x, int y) :m_x(x), m_y(y) { }
Point(const Point &point) :m_x(point.m_x), m_y(point.m_y) { } //const型参数可以接受const和非const实参,&可以避免中间对象的生成
bool operator==(const Point &point) {
if(m_x == point.m_x && m_y == point.m_y)
return true;
else
return false;
}
void display() {
cout << "x = " << this->m_x << ", y = " << this->m_y << endl;
}
-=:
class Point {
int m_x;
int m_y;
public:
Point(int x, int y) :m_x(x), m_y(y) { }
Point(const Point &point) :m_x(point.m_x), m_y(point.m_y) { } //const型参数可以接受const和非const实参,&可以避免中间对象的生成
bool operator!=(const Point &point) {
if(m_x != point.m_x || m_y != point.m_y)
return true;
else
return false;
}
void display() {
cout << "x = " << this->m_x << ", y = " << this->m_y << endl;
}
5. 其他:关于拷贝构造函数中的“&”
Point(const Point &point) { //相当于把p1的地址值传入了
m_x = point.m_x;
m_y = point.m_y;
}
Point p1;
Point p2 = p1; //调用拷贝构造函数
但是:
Point(const Point point) { //当接受p1时,Point p = p1,会再次调用拷贝构造函数,成为了死循环
m_x = point.m_x;
m_y = point.m_y;
}
Point p1;
Point p2 = p1; //调用拷贝构造函数
6. 单目运算符
-:
class Point {
int m_x;
int m_y;
public:
Point(int x, int y) :m_x(x), m_y(y) { }
Point(const Point &point) :m_x(point.m_x), m_y(point.m_y) { } //const型参数可以接受const和非const实参,&可以避免中间对象的生成
const Point operator-() const{
return Point(-m_x, -m_y); //因为允许(-(-x))
}
void display() {
cout << "x = " << this->m_x << ", y = " << this->m_y << endl;
}
前置++:
class Point {
int m_x;
int m_y;
public:
Point(int x, int y) :m_x(x), m_y(y) { }
Point(const Point &point) :m_x(point.m_x), m_y(point.m_y) { } //const型参数可以接受const和非const实参,&可以避免中间对象的生成
Point & operator++() {
m_x ++;
m_y ++;
return *this;
}
void display() {
cout << "x = " << this->m_x << ", y = " << this->m_y << endl;
}
};
后置++:
class Point {
public:
int m_x;
int m_y;
Point(int x, int y) :m_x(x), m_y(y) { }
Point(const Point &point) :m_x(point.m_x), m_y(point.m_y) { } //const型参数可以接受const和非const实参,&可以避免中间对象的生成
const Point operator++(int) { //允许b = a ++ + 1,但不允许a ++ = 1;
Point old(m_x, m_y);
m_x ++;
m_y ++;
return old;
}
void display() {
cout << "x = " << this->m_x << ", y = " << this->m_y << endl;
}
};
同理 --。
7. 输出与输出
输出:
class Point {
friend ostream &operator<<(ostream &, const Point &);
int m_x;
int m_y;
public:
Point(int x, int y) :m_x(x), m_y(y) { }
Point(const Point &point) :m_x(point.m_x), m_y(point.m_y) { } //const型参数可以接受const和非const实参,&可以避免中间对象的生成
void display() {
cout << "x = " << this->m_x << ", y = " << this->m_y << endl;
}
};
ostream &operator<<(ostream &cout, const Point &point) {
cout << "(" << point.m_x << "," << point.m_y << ")" << endl;
return cout; //返回cout对象,才能使用cout << a << b。实现多次重载;
}
输入:
class Point {
friend istream &operator>>(istream &, Point &);
int m_x;
int m_y;
public:
Point(int x, int y) :m_x(x), m_y(y) { }
Point(const Point &point) :m_x(point.m_x), m_y(point.m_y) { } //const型参数可以接受const和非const实参,&可以避免中间对象的生成
void display() {
cout << "x = " << this->m_x << ", y = " << this->m_y << endl;
}
};
istream &operator>>(istream &cin, Point &point) { //因为point对象允许被修改,所以不应该是const型对象(const对象不允许修改)
cin >> point.m_x;
cin >> point.m_y;
return cin;
}
调用父类的运算符重载函数
class Person {
int m_age;
public:
Person &operator=(const Person &person) {
this->m_age = person.m_age;
}
};
class Student : public Person {
int m_score;
public:
Student &operator= (const Student & student) {
Person::operator=(student);
this->m_score = student.m_score;
}
单例模式扩充
class Rocket {
private:
Rocket() {}
~Rocket() {} //防止用户在生成Rocket中delete掉对象
static Rocket *ms_rocket;
void operator=(const Rocket &rocket) { } //重载赋值运算符,不允许赋值
public:
static Rocket *sharedRockert() {
//这里要考虑多线程安全
if (ms_rocket == NULL) {
ms_rocket = new Rocket();
}
return ms_rocket;
}
static void deleteRocket() {
// 这里要考虑多线程安全
if (ms_rocket != NULL) {
delete ms_rocket; //只是堆空间的对象被释放了
ms_rocket = NULL; //ms_rocket指针仍然还在栈中,不会清零
}
}
};
Rocket *rocket::ms_rocket = NULL;
仿函数(函数对象)
- 仿函数:将一个对象当成一个函数一样来使用。
class Sum {
public:
int operator() (int a, int b) {
return a + b;
}
};
Sum sum;
cout << sum(20, 30) << endl;
- 对比普通函数,它作为对象可以保存状态。
运算符重载注意点
- 有些运算符不可以被重载,比如:
- 对象成员访问运算符:.
- 域运算符:::
- 三目运算符:?:
- sizeof
- 有些运算符只能重载为成员函数,比如:
- 赋值运算符:=
- 下标运算符:[]
- 函数运算符:()
- 指针访问成员:->