C++友元函数以及运算符重载

一、友元函数的作用

函数的私有和保护变量在类内可以访问,在类外只可访问公有变量;派生类在类内只可访问其基类的公有变量和保护变量,在类外只可访问其公有变量(要看具体的继承类型);

因此,在有些情况下,需要访问类的私有或保护变量时,不得不调用其成员函数,因为只有成员函数才有访问的权限。因而多出许多时间开销。

友元函数和类的成员函数的访问权限相同,但是其不是类的成员函数,它破坏了类的封装性;友元函数分为三类:普通的友元函数,友元类,和类的成员函数成为友元函数;


因为友元函数没有this指针,则参数要有三种情况:

2.1.1 要访问非static成员时,需要对象做参数;

2.1.2 要访问static成员或全局变量时,则不需要对象做参数;

2.1.3 如果做参数的对象是全局对象,则不需要对象做参数;

(1)普通友元函数:常用的就是运算符重载

#include <iostream>
using namespace std;

class time
{
	friend ostream& operator<<(ostream&,time& t);
private:
	int x;
	int y;
	int z;
	
public:
	time(int a,int b,int c):x(a),y(b),z(c){};
};

ostream& operator<<(ostream& out,time& t)
{
	out<<"("<<t.x<<t.y<<t.z<<")";
	return out;
}
int main()
{
	time t(1,2,3);
	cout<<t<<endl;

	return 0;
}

友元函数的位置是无关紧要的;

(2)友元类

#include <iostream>
using namespace std;
class A;
class time
{
	friend ostream& operator<<(ostream&,time& t);
private:
	int x;
	int y;
	int z;
	
public:
	time(int a,int b,int c):x(a),y(b),z(c){};
	friend A;
};

class A
{
private:
	int m;
	int n;
public:
	
	void test(time& t);
};
void A::test(time& t)
{
	m=t.x;
	n=t.y;
}
ostream& operator<<(ostream& out,time& t)
{
	out<<"("<<t.x<<t.y<<t.z<<")";
	return out;
}
int main()
{
	time t(1,2,3);
	cout<<t<<endl;
	A a;
	a.test(t);

	return 0;
}

使用单个声明使A类的所有函数成为类X的友元,它提供一种类之间合作的一种方式,使类A的对象可以具有类A和类time的功能

(3)类A的一个成员函数成为类B的友元函数

#include <iostream>
using namespace std;
class time;
class A
{
private:
	int m;
	int n;
public:
	void test(time& t);
};

class time
{
	friend void A::test(time& t);
	friend ostream& operator<<(ostream&,time& t);
private:
	int x;
	int y;
	int z;
	
public:
	time(int a,int b,int c):x(a),y(b),z(c){};
	
};


void A::test(time& t)
{
	m=t.x;
	n=t.y;
}
ostream& operator<<(ostream& out,time& t)
{
	out<<"("<<t.x<<t.y<<t.z<<")";
	return out;
}
int main()
{
	time t(1,2,3);
	cout<<t<<endl;
	A a;
	a.test(t);

	return 0;
}

注意: 此时类A的定义一定要在类time之前,此时test()函数的声明在类time之前,方为正确的,若在之后定义,则test()即使声明为友元函数,依然无法访问其私有变量;

ps:刚刚写的时候,利用头文件和cpp文件进行封装,在操作符重载函数前加了个inline 即

inline ostream& operator<<(ostream& out,time& t)
{
	return out<<"("<<t.x<<t.y<<t.z<<")";

}
将它放在了cpp文件中,总是报错,后将其和头文件放在一起,就没有错误了;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值