C++中的友元函数主要应用于以下场景:

友元函数

第一种场景

代码中有一个全局函数,该函数想要去访问某个类的成员变量(该类的成员变量是private的,且该类并未提供任何获取获取私有成员变量的public方法),这时候可以在这个类中把该全局函数声明为友元函数,这样这个全局函数就具备了能够获取那个类的私有成员变量的资格。

例:通过友元函数获取Person类的各项字段信息:

main.cpp

#include <iostream>
#include "Person.h" void showPersonInfo(Person *person)
{
std::cout << person->m_name << ", age is: " << person->m_age << ", sex is: " << person->m_sex << std::endl;
}
int main()
{
Person *person = new Person("xp.chen", 20, 1);
showPersonInfo(person);
delete person; getchar();
return 0;
}

person.h

#pragma once
class Person
{
private:
char *m_name;
int m_age;
int m_sex;
public:
Person(char *name, int age, int sex);
~Person();
public:
friend void showPersonInfo(Person *person); // 将showPersonInfo()函数声明为友元函数
};

person.cpp

#include "Person.h"

Person::Person(char *name, int age, int sex)
:m_name(name)
, m_age(age)
, m_sex(sex)
{
} Person::~Person()
{
}

运行结果:

xp.chen, age is: 20, sex is: 1

第二种场景

在某个类(假设为A类)有一个成员函数,该成员函数想去访问另一个类(假设为B类)中的私有成员变量。这时候则可以在第二个类(B类)中,声明第一个类(A类)的那个成员函数为友元函数,这样第一个类(A类)就可以访问第二个类(B类)的私有成员变量了。

例:打印Person类的详细信息(包含姓名,年龄,性别,省份,城市,街道)

Person.h

#pragma once

class Address;
class Person
{
private:
char *m_name;
int m_age;
int m_sex;
public:
Person(char *name, int age, int sex);
~Person();
public:
void showDetailInfo(Address *addr); // 用于打印包含姓名,年龄,性别,省份,城市,街道的详细信息
};

Address.h

#pragma once
#include "Person.h" class Address
{
private:
char *m_province;
char *m_city;
char *m_district; public:
Address(char *province, char *city, char *district);
~Address();
public:
friend void Person::showDetailInfo(Address *addr);
};

Address.cpp

#include "Address.h"

Address::Address(char *province, char *city, char *district)
:m_province(province)
, m_city(city)
, m_district(district)
{
} Address::~Address()
{
}

Person.cpp

#include <iostream>
#include "Address.h" Person::Person(char *name, int age, int sex)
:m_name(name)
, m_age(age)
, m_sex(sex)
{
} void Person::showDetailInfo(Address *addr)
{
std::cout << "Name: " << m_name << ", Age: " << m_age << ", Sex: " << m_sex << ", Province: " << addr->m_province << ", City: " << addr->m_city << ", District: " << addr->m_district << std::endl;
} Person::~Person()
{
}

main.cpp

#include <iostream>
#include <stdlib.h>
#include "Address.h" int main()
{
Person *person = new Person("xp.chen", , );
Address *address = new Address("JS", "KS", "ZhengRoad");
person->showDetailInfo(address); delete person, address;
system("pause");
return ;
}

运行结果:

Name: xp.chen, Age: 20, Sex: 1, Province: JS, City: KS, District: ZhengRoad

友元类

友元类则更简单,可以将一个类(类A)声明成另一个类(类B)的友元类,那么类A就拥有了能够访问类B所有成员的资格,包括private, protected, public的。

例:将上述例子中的Address.h修改成:

#pragma once
#include "Person.h" class Address
{
private:
char *m_province;
char *m_city;
char *m_district; public:
Address(char *province, char *city, char *district);
~Address();
public:
friend class Person;
};

声明类Person是类Address的友元类,再次运行程序:

Name: xp.chen, Age: 20, Sex: 1, Province: JS, City: KS, District: ZhengRoad

需要注意的是:

  • 友元的关系是单向的而不是双向的。如果声明了类 B 是类 A 的友元类,不等于类 A 是类 B 的友元类,类 A 中的成员函数不能访问类 B 中的 private 成员。
  • 友元的关系不能传递。如果类 B 是类 A 的友元类,类 C 是类 B 的友元类,不等于类 C 是类 A 的友元类。

另外,有的编译器也可以不写class关键字,也就是说可以写成:friend Person, 不过为了兼容性还是建议写上。

C++中的友元函数和友元类的更多相关文章

  1. C++学习12 友元函数和友元类

    友元函数和友元类在实际开发中较少使用,想快速学习C++的读者可以跳过本节. 一个类中可以有 public.protected.private 三种属性的成员,通过对象可以访问 public 成员,只有 ...

  2. C++:友元(非成员友元函数、成员友元函数、友元类)

    3.8  友元:友元函数和友元类 友元函数 :既可以是不属于任何类的非成员函数,也可以是另一个类的成员函数,统称为友元函数.友元函数不是当前类的成员函数,而是独立于类的外部函数,但它可以访问该类所有的 ...

  3. 友元(友元函数、友元类和友元成员函数) C++

    有些情况下,允许特定的非成员函数访问一个类的私有成员,同时仍阻止一般的访问,这是很方便做到的.例如被重载的操作符,如输入或输出操作符,经常需要访问类的私有数据成员. 友元(frend)机制允许一个类将 ...

  4. c++友元函数与友元类

    友元函数和友元类的需要: 类具有封装和信息隐藏的特性.只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的.非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这 ...

  5. C++ friend友元函数和友元类(转)

    一个类中可以有 public.protected.private 三种属性的成员,通过对象可以访问 public 成员,只有本类中的函数可以访问本类的 private 成员.现在,我们来介绍一种例外情 ...

  6. 2.19 C++友元函数和友元类

    参考: http://www.weixueyuan.net/view/6350.html 总结: 借助friend关键字将其声明为友元函数,结果,在display函数体内,我们就能访问private属 ...

  7. C++之友元函数和友元类

    通过friend关键字,我们可以将不属于当前类的一个函数在当前类中加以声明,该函数便可以成为当前类的友元函数. #include<iostream>using namespace std; ...

  8. 【C++基础 05】友元函数和友元类

    友元是一种定义在类外部的普通函数或类,但它须要在类体内进行说明,为了与该类的成员函数加以差别,在说明时前面加以keywordfriend. 友元不是成员函数,可是它能够訪问类中的私有成员. 友元的作用 ...

  9. C++友元函数、友元类

    1.什么是友元函数? 友元函数就是可以直接访问类的成员(包括私有数据)的非成员函数,也就是说他并不属于这个类,他是一种外部的函数. 一个外部函数只能通过类的授权成为这个类友元函数,这就涉及到一个关键字 ...

随机推荐

  1. fiddler怎么修改服务器返回参数并发送

    在进行使用fiddler中提供了较多的功能进行使用的,那么进行就可以对当前的网页中的暂停之后,在进行使用fiddler中把拦截起的后,在进行修改的服务器参数的之后,在把参数修改完成之后,把进行发送出去 ...

  2. Tomcat默认界面可导致版本信息泄露+管理后台爆破

    由于配置的Tomcat时,管理页面未进行删除或者权限角色配置,攻击者可以通过暴力猜解进入到管理后台,从而上传获取shell. Tomcat的默认工具manager配置,在很多的生产环境中由于基本用不到 ...

  3. yum安装提示错误Thread/process failed: Thread died in Berkeley DB library

    问题描述: yum 安装更新提示 rpmdb: Thread/process failed: Thread died in Berkeley DB library 问题解决: 01.删除yum临时库文 ...

  4. ubuntu下安装万能五笔

    之前一直习惯了万能五笔输入法,使用Ubuntu12.04安装wnwb 在网络上搜索了一下并没有找到可 以在ibus下直接使用万能五笔的方法,于是想自己动手解决这个问题, 参考别人之前做的万能五笔For ...

  5. sqlserver的convert函数

    定义和用法 CONVERT() 函数是把日期转换为新数据类型的通用函数. CONVERT() 函数可以用不同的格式显示日期/时间数据. 语法 CONVERT(data_type(length),dat ...

  6. 集成支付宝钱包支付 iOS SDK 的方法与经验

    下载 首先,你要想找到这个SDK,都得费点功夫.现在的SDK改名叫移动支付集成开发包了,下载页面在 这里 (http://t.cn/8ksiklD)的 “请点此下载集成开发包(http://t.cn/ ...

  7. 双链表实现Queue

    算法导论第10章的东西,感觉用双链表真心简单,就是有点浪费空间,但是时间复杂度O(1): #include <stdio.h> struct LinkNode { LinkNode(): ...

  8. iOS 一个小动画效果-b

    近期工作不忙,来一个需求感觉棒棒的,是一个比较简单的页面,如下图(图1) 图1 应该很简单吧,没什么大的功能,就是一个展示,一个拨打电话,拨打电话不需要说,几行代码搞定,基本UI也不用说了,刚培训完的 ...

  9. sql的行转列(PIVOT)与列转行(UNPIVOT) webapi 跨域问题 Dapper 链式查询 扩展 T4 代码生成 Demo (抽奖程序)

    sql的行转列(PIVOT)与列转行(UNPIVOT)   在做数据统计的时候,行转列,列转行是经常碰到的问题.case when方式太麻烦了,而且可扩展性不强,可以使用 PIVOT,UNPIVOT比 ...

  10. git server 搭建指南

    搭建git服务器的经验总结 一: Server端的设置 1. 安装 git, git-core 2. 安装 ssh-server. (代码上传通道) 3. 创建git 用户 指定其目录 和所在组 4. ...