C++——友元、函数重载、操作符重载

1.友元的用法

(1)在类中以friend关键字声明友元

(2)类的友元可以是其它类或者具体函数

(3)友元不是类的一部分

(4)友元不受类中访问级别的限制

(5)友元可以直接访问具体类的所有成员

复制代码
#include <stdio.h>
#include<math.h>
class Point {
	double x;
	double y;
	friend double func(Point& p1,Point& p2);
public:
	Point(int x, int y) {
		this->x=x;
		this->y=y;
	}
};
double func(Point& p1, Point& p2) {
	double ret = 0;
	ret = (p2.y - p1.y) * (p2.y - p1.y) + (p2.x - p1.x) * (p2.x - p1.x);
	ret = sqrt(ret);
	return ret;
}
int main() {
	Point p1(1,2);
	Point p2(10,20);
	printf("|(p1,p2)|=%f\n", func(p1, p2));
	return 0;
}

友元函数可以访问类中的私有属性,否则就要调用get函数去访问x和y,增加性能消耗

类的友元可以是其它类的成员函数,也可以是某个完整的类,但是不具备传递性

2.函数重载

(1)重载函数的本质为多个不同的函数

(2)函数名和参数列表是唯一的标识

(3)函数重载必须发生在同一个作用域中

复制代码
#include <stdio.h>
#include<string.h>
int main() {
	const char* s = "niuhuicong";
	char buf[15] = { 0 };
	strcpy(buf, s);
	strncpy(buf, s, sizeof(buf) - 1); //将s拷贝给buf,长度最多为sizeof(buf) - 1)
	printf("%s\n", buf);
	return 0;
}

但是strncpy这个函数很难记,所以我们将改为

复制代码
#include <stdio.h>
#include<string.h>
char* strcpy(char* buf, const char* str, unsigned int n) {
	return strncpy(buf, str, n);
}
int main() {
	const char* s = "niuhuicong";
	char buf[15] = { 0 };
	strcpy(buf, s, sizeof(buf) - 1);
	printf("%s\n", buf);
	return 0;
}

3.操作符重载

(1)复数相加

复制代码
#include <stdio.h>
#include<string.h>
class Complex {
	int a;
	int b;
public:
	Complex(int a = 0, int b = 0) {
		this->a = a;
		this->b = b;
	}
	int getA() {
		return a;
	}
	int getB() {
		return b;
	}
	friend Complex Add(const Complex& p1, const Complex& p2);
};
Complex Add(const Complex& p1, const Complex& p2) {
	Complex ret;
	ret.a = p1.a + p2.a;
	ret.b = p1.b + p2.b;
	return ret;
}
int main() {
	Complex c1 = { 1,2 };
	Complex c2 = { 3,4 };
	Complex c3 = Add(c1, c2);
	printf("c3.a=%d,c3.b=%d\n",c3.getA(), c3.getB());
	return 0;
}

C++中的重载能够扩展操作符的功能,操作符的重载以函数的方式进行,本质是特殊形式的函数扩展操作符的功能

通过operator关键字可以定义特殊的函数,本质是通过函数重载操作符

所以复数相加使用operator关键字的写法如下:

复制代码
#include <stdio.h>
#include<string.h>
class Complex {
	int a;
	int b;
public:
	Complex(int a = 0, int b = 0) {
		this->a = a;
		this->b = b;
	}
	int getA() {
		return a;
	}
	int getB() {
		return b;
	}
	friend Complex operator +(const Complex& p1, const Complex& p2);
};
Complex operator +(const Complex& p1, const Complex& p2) {
	Complex ret; 
	ret.a = p1.a + p2.a;
	ret.b = p1.b + p2.b;
	return ret;
}
int main() {
	Complex c1 = { 1,2 };
	Complex c2 = { 3,4 };
	Complex c3 = c1+c2;
	printf("c3.a=%d,c3.b=%d\n",c3.getA(), c3.getB());
	return 0;
}

可以将操作符重载函数定义为类的成员函数,比全局操作符重载函数少一个参数(左操作数),不需要依赖友元就可以完成操作符重载,当成员函数和全局函数中都有该操作符重载函数,则优先调用成员函数的实现版本

复制代码
#include <stdio.h>
#include<string.h>
class Complex {
	int a;
	int b;
public:
	Complex(int a = 0, int b = 0) {
		this->a = a;
		this->b = b;
	}
	int getA() {
		return a;
	}
	int getB() {
		return b;
	}
	Complex operator +(const Complex& p1) {
		Complex ret;
		ret.a = this->a + p1.a;
		ret.b = this->b + p1.b;
		return ret;
	}
};

int main() {
	Complex c1 = { 1,2 };
	Complex c2 = { 3,4 };
	Complex c3 = c1+c2;
	printf("c3.a=%d,c3.b=%d\n",c3.getA(), c3.getB());
	return 0;
}
相关推荐
小成202303202652 分钟前
C++~02运算符重载
开发语言·c++
emfuture12 分钟前
龙芯2K300 PLC 在拉丝机收线系统改造中的应用:硬件选型、张力控制与国产化替代实践
java·开发语言·智能制造·plc·国产化替代
geovindu26 分钟前
rust: Mediator Pattern
开发语言·后端·设计模式·rust·中介者模式·行为模式
传奇开心果编程36 分钟前
【Rust入门练中学】第8课:错误处理
开发语言·rust·错误处理·编程语言理论·通用编程语言
郑同学的笔记1 小时前
【c++随笔30】C++ 注册回调函数
开发语言·c++
七夜zippoe1 小时前
启元 Q1 腿部运动学逆解:Python 算站立下蹲关节角
开发语言·python·ai·机器人·腿部运动学
熊猫钓鱼>_>1 小时前
精准碰一碰近场分享与拖拽投送实战:把文件“碰“进另一台设备【鸿蒙心迹】
开发语言·华为·harmonyos·鸿蒙·openharmony
lengxuenong1 小时前
树状数组 · 信息学学习手册2-离散化与逆序对
c++·学习·算法
十二1 小时前
【洛谷题解】P1115 最大子段和(前缀和 + 维护最小前缀)
数据结构·c++·算法·蓝桥杯
CodeGL2 小时前
9、Python基础之IO编程
开发语言·数据库·python