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

2023-11-17

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;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • 关于xpath的安装

    1 xpath简介 使用xpath需要安装模块 pip install lxml 导入模块 from lxml import etree xpath是用来载xml中查找指定的元素 它是一种路径表达式 详细内容可在文档中查找 https de
  • linux中软链接的使用方法

    在 Linux 中的连结有两种 一种是类似 Windows 的快捷方式功能的档案 可以让你快速的链接到目标档案 或目彔 另一种则是透过文件系统的 inode 连结来产生新的文档名 而不是产生新档案 这种称为实体链接 hard link Ha
  • C++ std::Thread多线程和mutex锁通俗易懂

    记录学习过程 如有新的发现 随时补充 如有错误或补充 请各位大佬指正 一 前言 多线程有多种方式 std Thread boost Thread pthread Windows库等 本文只关注std Thread 可以跨平台运行 二 std
  • 已解决-NVIDIA安装程序失败-win10

    这个错误界面没截图 去别的地方盗过来一个 我的电脑显示cuda版本是11 0的 所以一直努力装11 0版本的 新电脑刚开始装的前几次还没问题 卸的次数多了报应就来了 一直报错 整的都快崩溃了 现在解决了 我装的是10 0版本的 把方法贴出来
  • 使用Docker伪分布式安装hadoop

    1 安装Docker Desktop 官网地址 2 下载linux内核更新包 安装好Docker重启之后 会自动提示安装它 官网地址 3 重启计算机后打开docker desktop 4 win r 打开 cmd窗口 5 拉取镜像 dock
  • 在linux服务器上进行VTM的cmake并进行编解码

    前不多言 直接进入主题 一 上传VTM源码至linux服务器端 源码压缩包可以去这个网站进行下载 二 上传后使用linux操作命令解压 unzip xxx zip 三 解压后进行cmake操作 输入命令行进行操作 第一步 进入至解压后的vt
  • git操作总结

    git操作总结 一 配置Git 1 配置用户信息 安装git后 第一件事是配置用户名和邮件地址 记录是谁对文件进行了修改 global命令运行一次 永久生效 git config global user name git config gl
  • pandas DataFrame.to_sql() 用法

    to sql 的语法如下 https pandas pydata org pandas docs stable reference api pandas DataFrame to sql html DataFrame to sql name
  • QT-子线程或自定义类操作访问主界面UI控件的几种方法

    前言 QT创建窗体工程 一般在MainWindow或Dialog类里可以直接通过ui指针访问控件 但是添加新的类后又如何访问呢 可以通过以下几种方式 1 将ui指针公开后直接访问 1 例如有个自己定义的类CustomClass 在自定义类里
  • autojs人像变换

    牙叔教程 简单易懂 产品简介 腾讯云神图 人像变换 Face Transformation 基于腾讯优图领先的人脸识别算法 提供人脸年龄变化 人脸性别转换等能力 用户上传照片即可得到实现男女性别切换 人脸变老 变年轻等效果 适用于社交娱乐
  • 1.3 【Mask-RCNN训练自己的数据集】---- Part Three: 用自己训练的模型进行测试(全部流程总结+部分释义)

    三 模型测试 import os import sys sys path remove opt ros kinetic lib python2 7 dist packages import random import math import
  • Linux文件权限一共10位长度,分成四段,每段表示

    1 文件类型 2 文件所有者的权限 3 文件所有者所在组的权限 4 其他用户的权限句号
  • 求两个有序数组的中位数

    leetcode 4 Median of Two Sorted Arrays 题目 给两个有序数组 长度为n和m 在 O log m n 时间内找出两个数组中所有数字的中位数 题解 参考讨论区大佬解法 递归分治方法 先上代码 include
  • c#读取csv到数组_使用C#将CSV文件读入数组 - c#

    我正在尝试创建一个将拉入 读取和分隔csv文件的代码 它有四列 没有标题 我一直在网上找几个小时 似乎没有人真正找到答案 所以我希望这里有人可以 读入后 由于它是设计的一部分 因此我需要能够将其拉得很特别 提前谢谢 参考方案 您的问题有点含
  • How to detect the encoding of a text file with Deno?

    How to detect the encoding of a text file with Python Python 中有一个有用的包 chardet 它有助于检测文件中使用的编码 实际上 没有程序可以 100 确信使用了哪种编码 这就
  • pgsql有dual表?

    在 PostgreSQL 中 没有类似于 Oracle 中的 DUAL 表的概念 然而 您可以使用匿名块 Anonymous Block 来创建一个临时的查询结果集 并在其中进行测试或操作 以下是一个使用匿名块创建临时表的示例 DO DEC
  • 利用SAM实现自动标注

    利用SAM实现自动标注 目录 利用SAM实现自动标注 一 下载安装 1 1 下载SAM Tool和SAM 1 2 下载SAM模型文件 1 3 安装SAM 二 配置项目 三 提取信息 四 获得SAM onnx文件 五 标注 六 格式转换 6
  • 提示 使用驱动器D:中的光盘之前需要将其格式化

    千万不要格式化 直接格式化是最low的做法 方法如下 方法一 chkdsk G f 其中G是你U盘的盘符 f是fix修复的意思 之后电脑就会自动开始修复 修复的时候会告诉你修复了多少多少 最后修复完了 如果硬盘较大就多等会 注意 在此期间不
  • 静息态fMRI状态依赖的有效连接

    文章来源于微信公众号 茗创科技 欢迎有兴趣的朋友搜索关注 导读 大脑在静息状态下存在着不同脑区间的功能连接 并且在多重稳态之间具有内在动态平衡过程 因此 探索特定状态下的功能连接 有利于以加深对精神疾病的理解 然而 与功能连接相比 有效连接
  • 【深入理解C++】运算符重载、插入和提取运算符、拷贝赋值运算符

    文章目录 1 运算符重载 2 重载为友元函数 3 重载为成员函数 4 插入和提取运算符 5 拷贝赋值运算符 5 1 深拷贝 1 运算符重载 运算符重载可以为运算符增加一些新的功能 C 中绝大部分的运算符允许重载 不能重载的运算符有以下几个