c++之友元函数和友元类

c++友元函数一些见解

1、为什么要引入友元函数:在实现类之间数据共享时,减少系统开销,提高效率
具体来说:为了使其他类的成员函数直接访问该类的私有变量

  即:允许外面的类或函数去访问类的私有变量和保护变量,从而使两个类共享同一函数

  优点:能够提高效率,表达简单、清晰

  缺点:友元函数破环了封装机制,尽量不使用成员函数,除非不得已的情况下才使用友元函数。

2、什么时候使用友元函数:

  1)运算符重载的某些场合需要使用友元。

  2)两个类要共享数据的时候

3、怎么使用友元函数:

友元函数的参数:

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

   1、  要访问非static成员时,需要对象做参数;--常用(友元函数常含有参数)

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

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

友元函数的位置:

   因为友元函数是类外的函数,所以它的声明可以放在类的私有段或公有段且没有区别。

友元函数的调用:

   可以直接调用友元函数,不需要通过对象或指针
  • 普通的友元函数
#include<iostream>

using namespace std;

class Date
{
	friend ostream& operator<<(ostream& _cout, const Date& d);
public:
	Date(int year, int mouth, int day)
		:_year(year)
		, _mouth(mouth)
		, _day(day)
	{}
private:
	int _year;
	int _mouth;
	int _day;
};


ostream& operator<<(ostream& _cout, const Date& d)
{
	_cout << d._year << ":" << d._mouth << ":" << d._day << endl;
	return _cout;
}

int main()
{
	Date d(2018, 11, 2);
	cout << d << endl;
	return 0;
}
  • 上面的代码我重载了 << 运算符。这里必须放在类外来定义,如果放在类中来定义的话,我的主函数中 cout<< d<< endl 只能这样写了:d<<cout<<endl;
  • 为什么呢?来看看下面代码。
  • 我的定义写在类中,那么会出现什么情况呢?操作符 << 只需要传两个参数,那么在类中这样定义就会传了三个参数,不要this 指针哦。有人说,那不传 ostream& _cout 不就好了,啊哈,行啊,那么第一个参数就是const Date& d。最后调用的就要是 d<<cout;这样子了。所以友元函数是必须的。
class Date
{
	ostream& operator<<(ostream& _cout, const Date& d)
	{
		_cout << d._year << ":" << d._mouth << ":" << d._day << endl;
		return _cout;
	}
public:
	Date(int year, int mouth, int day)
		:_year(year)
		, _mouth(mouth)
		, _day(day)
	{}
private:
	int _year;
	int _mouth;
	int _day;
};

总结:友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字。

问题1:友元函数能不能用const修饰?

回答:不能,在类中,const 修饰函数是修饰函数的什么?当然是类函数中的this指针了,那么友元函数有没有this指针呢?当然没有this指针了,所以友元函数不能用const修饰。

友元函数可访问类的私有成员,是不是类的成员函数?

回答:不是,可以这样理解,友元函数是类的好朋友,那么类中的私有成员我允许我的朋友来访问。

友元函数需要放在类的那里来声明呢?public?private?还是?

回答:友元函数可以在类定义的任何地方声明,不受类访问限定符限制

函数A是类A的友元函数,那么函数还能是类B 的友元函数呢?

回答:你肯定不止一个朋友吧。一个函数可以是多个类的友元函数。

除了友元函数,还有友元类。

c++.h

#include<iostream>

using namespace std;

class Date
{
	friend class Time;
public:
	Date(int,int,int);
	void Print();
private:
	int _year;
	int _mouth;
	int _day;
};

class Time
{
	friend class Date;
public:
	Time(int ,int ,int);
	void Print();
private:
	int _hour;
	int _minut;
	int _second;
};

c++.cpp

#include<iostream>
#include"c++.h"
using namespace std;

	Date::Date(int year = 1990, int mouth = 1, int day = 1)
		:_year(year)
		, _mouth(mouth)
		, _day(day)
	{}
	void Date::Print()
	{
		Time t(11,101,10);
		cout << _year << "-" << _mouth << "-" << _day << t._hour << "-" << t._minut << "-" << t._second << endl;
	}


	Time::Time(int hour = 11, int minut = 10, int second = 10)
		:_hour(hour)
		, _minut(minut)
		, _second(second)
	{}
	void Time::Print()
	{
		Date d(100, 101, 102);
		cout << d._year << "-" << d._mouth << "-" << d._day << _hour << "-" << _minut << "-" << _second << endl;
	}


void Func()
{
	Date d(100,101,102);
	d.Print();
	Time t(10,11,12);
	t.Print();
	
}

int main()
{
	Func();
	return 0;
}
  • 这个要看清楚友元函数必须要在头文件中声明,在另一个文件中来定义。为什么?你自己放在一个文件中你就知道了,我说不清楚。
  • 上面的例子是个友元类,友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。

注意:

  • 友元的优缺点
  • 优点:提高了程序运行效率
  • 缺点:破坏了类的封装性和隐藏性
  • 友元关系是单向的,不具有交换性。
  • 比如上述Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time 类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。
  • 友元关系不能传递 如果B是A的友元,C是B的友元,则不能说明C时A的友元。

猜你喜欢

转载自blog.csdn.net/qq_40421919/article/details/83663066