运算符重载可以为运算符增加一些新的功能。
C++ 中绝大部分的运算符允许重载,不能重载的运算符有以下几个:
.
成员访问运算符.*
成员指针访问运算符::
作用域运算符sizeof
长度运算符?:
条件运算符有些运算符只能重载为成员函数,比如:
=
[]
()
->
友元运算符函数没有 this
指针,若重载的是双目运算符,则参数表中有两个操作符;若重载的是单目运算符,则参数表中只有一个操作符。
#include
using namespace std;
class Point
{
int m_x;
int m_y;
friend Point operator+(const Point&, const Point&);
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;
}
void display()
{
cout << "(" << m_x << ", " << 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 p1(10, 20);
Point p2 = p1;
Point p3 = p1 + p2;
p3.display();
Point p4 = p1 + p2 + p3;
p4.display();
return 0;
}
#include
using namespace std;
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;
}
void display()
{
cout << "(" << m_x << ", " << m_y << ")" << endl;
}
// 重载加号
const Point operator+(const Point& point) const
{
return Point(m_x + point.m_x, m_y + point.m_y);
}
// 重载减号
const Point operator-(const Point& point) const
{
return Point(m_x - point.m_x, m_y - point.m_y);
}
// 重载+=
Point& operator+=(const Point& point)
{
m_x += point.m_x;
m_y += point.m_y;
return *this;
}
// 重载==
bool operator==(const Point& point) const
{
return (m_x == point.m_x) && (m_y == point.m_y);
}
// 重载!=
bool operator!=(const Point& point) const
{
return (m_x != point.m_x) || (m_y != point.m_y);
}
// 重载负号
const Point operator-() const
{
return Point(-m_x, -m_y);
}
// 重载前缀++
Point& operator++()
{
m_x++;
m_y++;
return *this;
}
// 重载后缀++
const Point operator++(int)
{
Point old(m_x, m_y);
m_x++;
m_y++;
return old;
}
};
int main()
{
return 0;
}
<<
左移运算符,因为被重载用于数据流的插入,所以又叫插入运算符;
>>
右移运算符,因为被重载用于从数据流中提取数据,所以又叫提取运算符;
插入运算符 <<
和提取运算符 >>
不能重载为类的成员函数,可以重载为类的友元函数。
#include
using namespace std;
class Point
{
int m_x;
int m_y;
friend ostream& operator<<(ostream&, const Point&);
friend istream& operator>>(istream&, Point&);
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;
}
};
// 重载插入运算符<<
ostream& operator<<(ostream& cout, const Point& point)
{
cout << "(" << point.m_x << ", " << point.m_y << ")";
return cout;
}
// 重载提取运算符>>
istream& operator>>(istream& cin, Point& point)
{
cin >> point.m_x;
cin >> point.m_y;
return cin;
}
int main()
{
Point p1(10, 20);
Point p2 = p1;
cin >> p2;
cout << p2 << endl;
return 0;
}
拷贝赋值运算符只能重载为类的成员函数,而不能把它重载为类的友元函数。
#include
using namespace std;
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;
}
// 拷贝赋值运算符
Point& operator=(const Point& point)
{
m_x = point.m_x;
m_y = point.m_y;
return *this;
}
};
int main()
{
Point p1(10, 20); // 带参构造函数
Point p2(30, 40); // 带参构造函数
Point p3 = p1; // 拷贝构造函数
p3 = p2; // 拷贝赋值运算符
return 0;
}
#include
using namespace std;
class Car
{
private:
char* m_name;
public:
// 构造函数
Car(const char* name = NULL)
{
if (!name)
{
m_name = new char[1] {};
}
else
{
m_name = new char[strlen(name) + 1] {}; // 申请新的堆空间
strcpy(m_name, name); // 拷贝字符串数据到新的堆空间
}
}
// 拷贝构造函数
Car(const Car& car)
{
m_name = new char[strlen(car.m_name) + 1] {}; // 申请新的堆空间
strcpy(m_name, car.m_name); // 拷贝字符串数据到新的堆空间
}
// 拷贝赋值运算符
Car& operator=(const Car& car)
{
if (this == &car) return *this;
delete[] m_name; // 释放掉原区域
m_name = new char[strlen(car.m_name) + 1] {}; // 申请新的堆空间
strcpy(m_name, car.m_name); // 拷贝字符串数据到新的堆空间
return *this;
}
// 析构函数
~Car()
{
delete[] m_name;
m_name = NULL;
}
void display()
{
cout << "name is " << m_name << endl;
}
};
int main()
{
Car car1("bmw"); // 构造函数
Car car2("byd"); // 构造函数
Car car3 = car1; // 拷贝构造函数
car3 = car2; // 拷贝赋值运算符
car3.display();
return 0;
}