面试的时候面试官问到了友元函数,自己其实之前对友元函数不是特别熟悉,只是略知一二;当然,回答的不是很让面试官满意,今天总体的再学习一下友元函数。
1.什么是友元函数?
特点:
①在类中声明的以friend关键字修饰的函数。
②形式表现:friend 返回类型 函数名 参数列表;
#include<iostream>
class func{
public:
func(int a)
: m_a(a)
{}
void generalFunc();
friend void friendfunc(); //该友元函数声明为public类型。
private:
friend void friendfunc(); //当然,友元函数也可以声明为private类型。
private:
int m_a;
}
//实现普通成员函数
void func::generalFunc() //普通成员函数在类外实现时,需要类名+::操作符
{
std::cout<<"This is generalFunc!"<<std::endl;
}
//实现友元函数 友元函数要在类外实现。
void friendFunc() //友元函数在类外实现的时候不需要带类名。(因为他压根不是该类的成员函数)
{
std::cout<<"This is func's friend function!"<<std::endl;
}
2.什么是友元类?
看了友元函数,可以联想到友元类其实也是一样的道理。
#include<iostream>
class A{
public:
A();
void func(int a)
{
std::cout << "A::func()" << std::endl;
}
private:
friend class Afrifunc; //Afrifunc是类A的友元类
int m_a;
}
class Afrifunc{ //实现友元类Afrifunc
//...
}
class B{
public:
B();
friend void A::func(int a); //类A的成员函数作为了类B的友元函数。
private:
int m_b;
}
3.学会实现友元了,那我们使用的时候应该注意以下几点:
①友元函数不能直接访问类的成员,只能访问对象成员。
②友元函数可以访问对象的私有成员(这点普通函数不具备)
③调用友元时候要指出具体的对象。
④友元函数和友元类不继承(因为它压根不属于当前函数的成员)
⑤如上举例所示,一个类的成员可以作为另一个类的友元函数。
4.最重要的一点来了:
面试官这时候会问你,什么时候使用友元函数?使用它的好与坏都有什么?
1.先回到第一个问题,当我们需要提高效率或者为了方便,我们会使用它。因为普通函数无法访问私有的成员,除非全部声明为共有的。但是有了友元这个机制,我们就可以访问到对象的私有成员和数据了。
2.好处上面已经说了,是为了方便和快速。但是它明显的带来了一定的坏处,那就是破坏了类的封装性。(我校招的时候,某金融企业面试官问我继承的缺点,实际上我想,继承本身是为了构建父子关系,但是它从一定程度上讲,确实是破坏了子类的封装性,因为一个类被封装了之后就表面其内容对其他类是不可见的,但是继承却可以通过不同的方式看到父类的一些信息。当然,这只是我个人体会的)。