C++进阶剖析( 十 五)之操作符重载

本文详细介绍了C++中的操作符重载概念,包括复数类中的加法操作符重载,深拷贝时的等于操作符重载,以及用于输出的左移操作符重载。通过实例代码展示了不同重载方法的实现方式,如友元函数和成员函数的使用,同时解释了为何在某些情况下需要使用友元函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.1 复数类
-重载能够扩展系统中已经存在的函数功能 ,那么重载是否能扩展其他更多的功能?

1.1.1案例引出
在这里插入图片描述
1.1.2 解决一:实例代码
下面的代码使用了 友元语法。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
class  Complex
{
private:
	int mi;
	int mj;
public:
	Complex(int i=0 ,int j =0)
	{
		mi =i;
		mj =j;
	}
	int getI()
	{
		return mi;
	}
	int getJ()
	{
		return mj;
	}
friend Complex  add(const Complex &obj1,const Complex&obj2);    // 重要

};

Complex  add(const Complex &obj1,const Complex&obj2)
{
	Complex ret;
	ret.mi =obj1.mi + obj2.mi;
	ret.mj = obj1.mj + obj2.mj;
	return ret;

}
int main()
{	
	Complex c1(1,2);
	Complex c2(3,4);
	Complex c3 =add(c1,c2);
	printf("c3.mi =%d , c3.mj = %d \n",c3.getI(),c3.getJ());
	return 0;

}

1.1.3 解决二:实例代码
下面的代码使用了操作符重载的思想,注意比较方法二和方法一的不同之处。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
class  Complex
{
private:
	int mi;
	int mj;
public:
	Complex(int i=0 ,int j =0)
	{
		mi =i;
		mj =j;
	}
	int getI()
	{
		return mi;
	}
	int getJ()
	{
		return mj;
	}
	Complex operator+(const Complex& obj2)
	{
		Complex c3 ;
		c3.mi =this->mi + obj2.mi;
		c3.mj = this->mj +obj2.mj;
		return c3;
	}

};
int main()
{	
	Complex c1(1,2);
	Complex c2(3,4);
	Complex c3 = c1 +c2;
	printf("c3.mi =%d , c3.mj = %d \n",c3.getI(),c3.getJ());
	return 0;
}

1.2 “=” 操作符重载
1.2.1伪码
重载 = 操作符 实现深copy

class Name
{
private:
	char * m_p
	int len;
	
	//重载 = 操作符
	void  operator =(const Name & obj)
	{
	//1.释放之前的内存空间
		if(m_p != NULL)
		{
		 delete[] m_p;
		 m_p= NULL;
		}
		len = obj.len;
		//2.创建新的内存空间,并copy 数据
		m_p= new char[len+1];
		if(m_p!= NULL)
		{
			strcpy(m_p,obj.m_p);
		}
		return ;
	}
}

//上面的程序在下面的情况下会报错
obj1 = obj2 =obj3;
// 改进方式
Name & operator(Name &obj1)
{
  .....
  return *this;
}

1.2.2 什么时候需要进行“= ” 重载
使用系统资源的时候。只要 定义了copy构造函数就需要对“=”进行重载

  • C++中规定赋值操作符(=) 只能重载为成员函数
  • 操作符重载不能改变原操作符的优先级
  • 操作符重载不能改变操作数的个数
  • 操作符重载不应该把操作符的原有语义

对‘=’进行操作符重载不能改变操作符的原有语义,所以返回值是引用而不是变量

1.3 重载 << 操作符
1.3.1

  • 操作符 << 的原生语义是按位左移 比如: 1 << 2;其意义是将整数按位左移2位,即 00000001 ===>0000 0100
  • 重载左移操作符,将变量或常量左移到一个对象中
    ,
    1.3.2 案例1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char endl ='\n';
class Console // Console命令行
{
public:
	Console& operator<<(int i)
	{
		printf("%d",i);
		return *this;
	}
	Console& operator<<(const char * s)
	{
		printf("%s",s);
		return *this;		
	}
	Console& operator<<(char c)
	{
		printf("%c",c);
		return *this;
	}

};
Console  cout;
int main()
{	
	cout << "zhangsan"<<endl;
	cout << 1 <<endl;
	return 0;
}

1.3.3 C++中的标准库

  • C++标准库并不是C++语言的一部分
  • C++标准库是由类库和函数库组成的集合
  • C++标准库中定义的类和队形都位于std命名空间中
  • C++标准库的头文件都不带.h后缀
  • C++标准库涵盖了C库的功能
  • C++标准库预定义了多数常用的数据结构
    <bitset > <set> <cstdio>
    <deque> <stack> <cstring>
    <list> <vector> <cstdlib>
    <queue> <map> <cmath>

1.3.4案例2

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char endl ='\n';
class Console
{
public:
	Console& operator<<(int i)
	{
		printf("%d",i);
		return *this;
	}
	Console& operator<<(const char * s)
	{
		printf("%s",s);
		return *this;
		
	}
	Console& operator<<(char c)
	{
		printf("%c",c);
		return *this;
	}

};
Console  cout;

class Test
{
private:
	int ma;
	int mb;
public:
	Test(int a =0 ,int b =0)
	{
		ma = a;
		mb =b;
	}
	friend Console& operator<<(Console& out, const Test & obj);

};

Console& operator<<(Console& out, const Test & obj)
{
	out << obj.ma  <<":aafddsfasdf:"<< obj.mb << endl;
	return out;
}
int main()
{	
	Test t1(1,2);
	cout << t1 ;

	return 0;
}

思考: 为啥上面用了友元的方式来重载"<< "?
原因: 上面的案例只是进行测试用的, 实际上,我们如果要重载 <<,我们的友元函数是这样的。

friend  ostream& operator<<(ostream& out ,const Test &obj);

因为我们不能获取类ostream的源码,所以需要用到友元的方式来进行。

1.4
1.4.1 重载 []
int& operator [] (int index);
1.4.2 重载 ()
重载() 就是后面所说的函数对象分析的内容

参考一 :狄泰软件学院C++进阶剖析
参考二 : C++ primer中文版
如有侵权:请联系邮箱 1986005934@qq.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值