目录
1. 友元
1.1 概念
类实现了数据的隐藏和封装,类的数据成员一般定义为私有成员,仅能通过类的成员函数才能读写。如果数据成员定义为公共的,则又破坏了封装性。但是在某些情况下,需要频繁读写类的数据成员,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间开销,而影响程序的运行效率。
友元实现方式:
● 友元函数
● 友元类
● 友元成员函数
友元的优缺点:
友元在于提高程序的运行效率,但是,他破坏了类的封装性和隐藏性,使得非成员函数能够访问类的私有成员。导致程序维护性变差,因此使用友元要慎重。
1.2 友元函数
友元函数不属于任何一个类,是一个类外的函数,但是需要在内类进行声明。虽然友元函数不是类中的函数,但是却可以访问类中的所有成员(包括私有成员)。
为了使该类的成员函数进行区分,在声明前面加一个关键字friend。
一般函数只能访问类中的公有成员。
友元函数使用注意事项:
● 友元函数没有this指针
● 友元函数的声明可以放置到类中的任何位置,不受权限修饰符的影响
● 一个友元函数可以访问多个类,只需要在各个类中分别“声明“
友元函数访问实例:
// 友元函数,类内声明,以下两个函数都是友元函数,虽然函数名字一样,但是参数不一样。
friend void and_test(Test &t, Demo &d); 同时是类Test 与类Demo的友元函数,可以访问两个类中的成员。
friend void and_test(Test &t); 只是类Test 的友元函数,只可以访问Test 类中的成员。
#include <iostream>
using namespace std;
class Demo;
class Test
{
private:
int a;
public:
Test(int i):a(i){}
void show()
{
cout << a << " " << &a << endl;
}
// 友元函数,类内声明
friend void and_test(Test &t, Demo &d);
friend void and_test(Test &t);
};
class Demo
{
private:
int a;
public:
Demo(int i):a(i){}
void show()
{
cout << a << " " << &a << endl;
}
// 友元函数,类内声明
friend void and_test(Test &t, Demo &d);
};
// 友元函数
void and_test(Test &t, Demo &d)
{
cout << ++t.a << " " << &t.a << endl;
cout << ++d.a << " " << &d.a << endl;
}
void and_test(Test &t)
{
cout << ++t.a << " " << &t.a << endl;
}
int main()
{
Test t1(1);
Demo d1(2);
and_test(t1,d1);
and_test(t1);
t1.show();
return 0;
}
1.3 友元类
当一个类B成为了另一个类Test的朋友时,类B可以访问类Test的所有成员,此时类B就是类Test的友元类。
友元类的使用需要注意以下几点:
● 友元关系不能被继承
● 友元关系不具有交换性(比如:类B声明成类Test的友元,类B可以访问类Test中的成员,但是类Test不能访问类B中的私有成员,如果需要访问,需要将类Test声明成类B的友元)互为友元。
友元类实例:
类Demo 是类 Test的友元类,所以类Demo中的构造函数可以访问类Test中的成员变量。
#include <iostream>
using namespace std;
class Test
{
private:
int a;
public:
Test(int i):a(i){}
void show()
{
cout << "a= " << a << endl;
}
// 友元类,类内声明
friend class Demo;
};
// 友元类
class Demo
{
public:
void and_test(Test &t1)
{
cout << ++t1.a << " " << &t1.a << endl;
}
void and_test2(Test &t1)
{
cout << ++t1.a << " " << &t1.a << endl;
}
};
int main()
{
cout << "Hello World!" << endl;
Test t1(1);
Demo d;
d.and_test(t1);
d.and_test2(t1);
t1.show();
return 0;
}
1.4 友元成员函数
一个A类内的成员函数是另一个B类的友元,这个成员函数可以访问B类内的成员。只需要在类B中声明类A的成员函数是类B的友元就可以了。
友元成员使用步骤:
- 在一个A类内声明成员函数
- 在A类外定义上述成员函数
- 在B类内声明上述成员函数为友元
- 在A类之前声明被访问的B类
友元成员函数实例:
类B中的 void and_test(Test &t); 就是友元成员函数,该成员函数可以访问类 Test中的成员变量。
#include <iostream>
using namespace std;
// 第四步:声明被访问的类
class Test;
class B
{
public:
// 第二步:声明友元成员函数(类内声明,类外实现)
void and_test(Test &t);
};
class Test
{
private:
int a;
public:
Test(int i):a(i){}
void show()
{
cout << a << " " << &a << endl;
}
// 友元成员函数,类内声明 第一步
friend void B::and_test(Test &t);
};
// 第三步:类外实现友元成员函数
void B::and_test(Test &t)
{
cout << ++t.a << " " << &t.a << endl;
}
int main()
{
Test t1(1);
B b;
b.and_test(t1);
t1.show();
return 0;
}