【深入理解C++】运算符重载、插入和提取运算符、拷贝赋值运算符

1.运算符重载

运算符重载可以为运算符增加一些新的功能。

C++ 中绝大部分的运算符允许重载,不能重载的运算符有以下几个:

  • . 成员访问运算符
  • .* 成员指针访问运算符
  • :: 作用域运算符
  • sizeof 长度运算符
  • ?: 条件运算符

有些运算符只能重载为成员函数,比如:

  • 赋值运算符 =
  • 下标运算符 []
  • 函数运算符 ()
  • 指针访问成员 ->

2.重载为友元函数

友元运算符函数没有 this 指针,若重载的是双目运算符,则参数表中有两个操作符;若重载的是单目运算符,则参数表中只有一个操作符。

#include <iostream>
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;
}

3.重载为成员函数

#include <iostream>
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;
}

4.插入和提取运算符

<< 左移运算符,因为被重载用于数据流的插入,所以又叫插入运算符;

>> 右移运算符,因为被重载用于从数据流中提取数据,所以又叫提取运算符;

插入运算符 << 和提取运算符 >> 不能重载为类的成员函数,可以重载为类的友元函数。

#include <iostream>
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;
}

5.拷贝赋值运算符

拷贝赋值运算符只能重载为类的成员函数,而不能把它重载为类的友元函数。

#include <iostream>
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;
}

5.1 深拷贝

#include <iostream>
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;
}
  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值