c++友元 friend

一、概念

定义:

类实现了数据的隐藏与封装,类的数据成员一般定义为私有成员,仅能通过类的成员函数才能读写。如果数据成员定义为公共的,则又破坏了封装性。但是某些情况下,需要频繁读写类的成员,特别是在对某些成员函数多次调用时,由于参数传递、类型检查和安全性检查等都需要时间开销,而影响程序的运行效率。友元是一种定义在类外部的普通函数,但他需要在类体内进行说明,为了和该类的成员函数加以区别,在说明时前面加以关键字friend。友元不是成员函数,但是他能够访问类中的所有成员。

作用:

在于提高程序的运行效率,但是,他破坏了类的封装性和隐藏性,使得非成员函数能够访问类的私有成员。导致程序维护性变差,因此使用友元要慎用。友元较为实际的应用是在运算符重载,这种应用可以提高软件系统的灵活性。

分类:

  • 友元函数
  • 友元类
  • 友元成员函数

二、友元函数

#include <iostream>

using namespace std;

class Girl

{

private:

int age;

public:

Girl(int age):age(age){}

int get_age() const

{

cout << &age << endl;

return 18;

}

// 1. "声明"友元函数

friend void access_true_age(Girl&);

};

// 2. 定义友元函数

void access_true_age(Girl& g)

{

// 突破权限

cout << &g.age << endl;

cout << "真实年龄:" << g.age << endl;

// 修改

g.age = 18;

cout << "修改后年龄:" << g.age << endl;

}

int main()

{

Girl g(45);

cout << g.get_age() << endl;

// 通过友元函数访问Girl的年龄

access_true_age(g);

return 0;

}

  • 由于不属于类的成员函数,因此友元函数没有this指针,访问类的成员只能通过对象。
  • 友元函数在类中的“声明”可以写在类的任何部分,不受权限修饰符的影响。
  • 理论上一个友元函数可以是多个类的友元函数,只需要在各个类中分别“声明”。

三、友元类

当一个类B成为了另一个类A的友元类时,类B可以访问类A的所有成员。

需要注意的是:

  • 友元关系是单向的,不具有交换性。

如果类B是类A的友元类,类A不一定是类B的友元类。

  • 友元关系不具有传递性。

如果类C是类B的友元类,类B是类A的友元类,类C不一定是类A的友元类。

  • 友元关系不能被继承。

#include <iostream>

using namespace std;

class A

{

private:

string str = "A私有";

// “声明”友元类

friend class B;

};

class B

{

public:

void func(A& a)

{

// cout << this->str << endl; 错误:this是B对象不是A对象

cout << a.str << endl;

a.str = "我改了";

cout << a.str << endl;

}

};

int main()

{

A a;

// cout << a.str << endl; 错误

B b;

b.func(a);

return 0;

}

四、友元成员函数

在友元类的任何成员函数中都可以访问其他类的成员,但是友元成员函数把友元范围限制在一个成员函数中。

例如,类B的某个成员函数称为了类A的友元成员函数,这样类B的该成员函数就可以访问类A的所有成员了。

#include <iostream>

using namespace std;

// 3. 因为第二步中用到了类A,提前声明类A

class A;

// 2. 编写类B,并真正声明友元成员函数

class B

{

public:

void func(A&);

};

class A

{

private:

string str = "A私有";

// 1. 确定友元的函数格式并“声明”

friend void B::func(A&);

};

// 4. 类外定义友元成员函数

void B::func(A & a)

{

// cout << this->str << endl; 错误:this是B对象不是A对象

cout << a.str << endl;

a.str = "我改了";

cout << a.str << endl;

}

int main()

{

A a;

// cout << a.str << endl; 错误

B b;

b.func(a);

return 0;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值