C++ 友元函数和友元类

前言

        在本文中,您将学习在C ++中创建友元函数和友元类,并在程序中有效地使用它们。OOP的重要概念之一是数据隐藏,即非成员函数无法访问对象的私有或受保护的数据。但是,有时这种限制可能迫使程序员编写冗长而复杂的代码。因此,C ++编程内置了一种机制,可以从非成员函数访问私有或受保护的数据,这是使用友元函数和友元类完成的。

C ++中的友元函数

        如果将函数定义为友元函数,则可以使用函数访问类的私有数据和受保护数据。通过使用关键字friend,编译器知道给定的函数是友元函数。要访问数据,应该在类的内部以关键字friend开始声明友元函数(可以是类内部的任何地方,可以是private部分,也可以是public部分)。

C ++中的友元函数声明

class class_name
{... .. ...friend return_type function_name(argument/s);... .. ...
}

现在,您可以将友元函数定义为访问该类数据的普通函数。friend定义中未使用任何关键字。

class className
{... .. ...friend return_type functionName(argument/s);... .. ...
}return_type functionName(argument/s)
{... .. ...// 可以从这个位置访问className的私有和受保护数据//因为此函数是className的友元函数。... .. ...
}

 

/* C ++程序演示友元函数的工作。*/
#include<iostream>
class base {
public:// 友元函数friend int display_friend(base);
private:int a = 1;
protected:int b = 2;
};// 友元函数的定义
int display_friend(base m) {//从非成员函数访问私有数据和受保护数据int c = m.a + m.b;return c;
}int main() {base base1;std::cout << "输出:" << display_friend(base1) << std::endl;system("pause");return 0;
}

输出结果:

3

分析:

        这里,友元函数display_friend() 在base类中声明。因此,可以从这个函数访问类中的私有数据和受保护数据。

若将友元函数在类中的声明去掉,则程序会报错:
去掉友元函数在类中的声明之后代码如下:

/* C ++程序演示友元函数的工作。*/
#include<iostream>
class base {
public:// 友元函数//friend int display_friend(base);
private:int a = 1;
protected:int b = 2;
};// 友元函数的定义
int display_friend(base m) {//从非成员函数访问私有数据和受保护数据int c = m.a + m.b;return c;
}int main() {base base1;std::cout << "输出:" << display_friend(base1) << std::endl;system("pause");return 0;
}

编译器报错: 

使用友元函数添加两个不同类的私有或受保护成员变量

#include<iostream>
class base2; // 类base2的前置声明class base1 {
public:// 友元函数声明friend int display_friend(base1, base2);
private:int a = 1;
};class base2 {
public:// 友元函数声明friend int display_friend(base1, base2);protected:int b = 2;
};// 友元函数的定义
// 函数display_friend()是类base1和base2的友元函数
int display_friend(base1 m1, base2 m2) {//从非成员函数访问私有数据和受保护数据int c = m1.a + m2.b;return c;
}int main() {base1 A;base2 B;std::cout << "输出:" << display_friend(A, B) << std::endl;system("pause");return 0;
}

 输出结果:

3

分析:

        在这个程序中,类base1和base2已经将display_friend()声明为friend函数。因此,这个函数可以访问这两个类的私有数据或受保护数据。在这里,display_friend()函数将两个对象A和B的私有数据 a 和受保护数据 b 相加,并将其返回给main函数。

        为了使这个程序正常工作,应该像上面的实例中所示的那样,对一个类base2进行前置声明。这是因为使用以下代码在class base1中引用了class base2的友元函数:friend int display_friend(base1,base2);

友元类(friend class)

        类似地,像一个友元函数一样,一个类也可以使用关键字friend成为另一个类的友元类。例如:

... .. ...
class B;
class A
{// class B 是 class A的友元类friend class B;... .. ...
}class B
{... .. ...
}

        当一个类成为另一个类的friend类(友元类)时,这就意味着这个类的所有成员函数都是另一个类的友元函数。

        在这个程序中,B类的所有成员函数都是A类的朋友函数,因此B类的任何成员函数都可以访问A类的私有和受保护的数据,但是A类的成员函数不能访问B类的数据。

例如下面的代码:

#include<iostream>
class B; // 前置声明class A {// class B 是class A的友元类friend class B;private:int a = 1;
protected:int b = 2;
};class B {public:// 类B的成员函数int displayB(A a1) {int c = a1.a + a1.b;return c;}
};int main() {A a2;B b2;std::cout << b2.displayB(a2) << std::endl;
}

输出结果:

3

分析: 

        类B 为类A 的友元类,类B中的成员函数可以访问类A的私有数据和受保护数据。

C ++编程中如何互为友元类

        如何实现classA与B互为友元,即A可以访问B的私有,B也可以访问A的私有呢?案例如下:

#include<iostream>
class B; // 前置声明class A {// class B 是class A的友元类friend class B;private:int a = 1;
protected:int b = 2;
public:int displayA(B);
};class B {// class A 是class B 的友元类friend class A;public:// 类B的成员函数int displayB(A a1) {int c = a1.a + a1.b;return c;}
private:int e = 3;
protected:int f = 4;
};// 类A的成员函数
int A::displayA(B b1) {int g = b1.e + b1.f;return g;
}int main() {A a2;B b2;std::cout << b2.displayB(a2) << std::endl; // 3std::cout << a2.displayA(b2) << std::endl; // 7
}

输出结果:
3
7

互为友元类的做法就是,在class A中声明friend class B;在classB 中声明friend class A;

注意:类A中使用到了类B的地方必须在类B的声明后定义,在类A中只能声明。例如上边类A中的displayA() 函数,不能在类A中直接定义,只能放在类B的声明之后定义。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/165439.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AJAX: 对话框大全

AJAX:$.ajax({url: "/admin/cutting/getDataWeek",type: "GET",data:{},dataType:json,success: function (res) {if (res.code 1) {}},error:function (error) {console.log(请求失败);console.log(error);}}); $(.sub).unbind(click).click(funct…

Note——torch.size() umr_maximum() array.max() itertools.product()

torch.size Problem TypeError: ‘torch.Size’ object is not callable Reason Analysis torch.Size函数不可调用 因为torch只可以.size() 或 shape Solution 将y.shape()替换为y.size() 或 y.shape ytorch.normal(0,0.01,y.size())2 return umr_maximum(a, axis, None…

【斗罗二】天梦哥告白冰帝,唐三再返场,雨浩通过冰帝考验,觉醒新武魂

Hello,小伙伴们&#xff0c;我是小郑继续为大家深度解析斗罗大陆2绝世唐门国漫资讯。 斗罗大陆动画第二部绝世唐门第19集已经更新了&#xff0c;全都是霍雨浩与天梦哥在极北之地&#xff0c;吸引冰帝加入造神计划的过程。不仅有天梦哥的爱情宣言告白&#xff0c;唐三也再次限时…

Python学习笔记——类、魔术方法

食用说明&#xff1a;本笔记适用于有一定编程基础的伙伴们。希望有助于各位&#xff01; 类 类的运用很常见&#xff1a;在大部分情况下&#xff0c;对一些特有的对象&#xff0c;可以使用特定的类来指向它&#xff1a; class Person:name unknownage -1sex 0partner No…

逗号表达式

#include<stdio.h> int cmp() {return(2,1); } int main() {int z cmp();printf("%d",z);return 0; } 逗号表达式括号里的优先级是自左向右&#xff0c;最后一个值为最终的结果。

反向传播back propagation

深度学习概述 决定要怎么连接这些neuron的时候 就已经确定了function set 相比于之前做logistic regression&#xff0c;linear regression的时候&#xff0c;换一个方式来决定function set 比较大&#xff0c;包含了logistic regression&#xff0c;linear regression没法包含…

01、Python 安装 ,Pycharm 安装

目录 安装安装 Python安装 Pycharm 创建项目简单添加文件运行 简单爬取下载小视频 安装 python-3.8.10-amd64.exe – 先安装这个 pycharm-community-2022.2.exe 再安装这个 安装 Python python-3.8.10-amd64.exe 安装&#xff08;这个是其他版本的安装&#xff0c;步骤一样…

[C++]3.类和对象下(this指针补充)+ 类和对象中构造函数和析构函数。

类和对象下&#xff08;this指针补充&#xff09; 类和对象中构造函数和析构函数 一.this补充&#xff1a;1.概念总结&#xff1a;2.两个问题&#xff1a; 二.构造函数和析构函数&#xff1a;一.类的默认构造&#xff1a;1.初始化和清理&#xff1a;2.拷贝复制&#xff1a;3.取…

打卡go学习第一天

8.1 下面展示一些 代码。 package mainimport ("fmt""net""os""time" )type Clock struct {Name stringAddr string &#xff5d; func main() {clocks : []Clock{{Name: "New York", Addr: "localhost:8000"…

基于深度学习网络的蔬菜水果种类识别算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1数据集准备 4.2构建深度学习模型 4.3模型训练 4.4模型评估 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 clc; clear; close all; wa…

如何更换微信公众号主体?

公众号迁移有什么作用&#xff1f;只能变更主体吗&#xff1f;微信公众平台的帐号迁移功能可将原公众号的粉丝、文章素材、违规记录、留言功能、名称等迁移至新的公众号。通过迁移可以实现公众号的公司主体变更、粉丝转移、开通留言功能、服务号转为订阅号等作用。因此不止局限…

CAD Exchanger SDK 3.22.0 Crack

Docker 映像、Autodesk Inventor 2022 支持以及从 CAD Exchanger 3.22.0 中的 CATIA 导入属性 使用 Docker 映像将您的软件运送到任何地方&#xff0c;独立于 Autodesk 软件读取 .ipt、.iam 文件&#xff0c;从 CATIA 探索机械、产品和自定义属性。 软件开发工具包产品更新发明…

使用 Rust 开发:以太坊与 Layer2 生态建设新趋势

Rust 是一种系统编程语言&#xff0c;以其出色的性能、内存安全和并发性而闻名&#xff0c;在区块链和 Web3 中广泛应用&#xff0c;大多数编程语言和开发框架都以 Rust 为核心&#xff0c;如 Polkadot、Solana、NEAR、Elrond&#xff08;现名 MultiversX&#xff09;、Hyperle…

华为云文件上传(单个上传和分段上传)

首先引入静态文件&#xff1a; 华为云官网提供js下载的链接 然后后端提供一个公用接口&#xff0c;返回华为云上传的基本配置&#xff1a; 官网提供的链接&#xff1a;华为云obs信息配置 一&#xff1a;单个上传 huaweiyunUpload (file, fileName, name, url, size, callb…

13.3测试用例进阶

一.测试对象划分 1.界面测试(参考软件规格说明书和UI视觉稿) a.什么是界面 1)WEB站(浏览器) 2)app 3)小程序 4)公众号 b.测试内容 1)界面内容显示的一致性,完整性,准确性,友好性.比如界面内容对屏幕大小的自适应,换行,内容是否全部清晰展示. 2)验证整个界面布局和排版…

设计模式_中介者模式

中介者模式 介绍 设计模式定义案例问题堆积在哪里解决办法中介者代替了多个对象之间的互动 使对象1 2 3 之间的互动 变为&#xff1a; 对象1->中介 对象2->中介 对象3->中介好友之间 约饭好友1 通知 好友2 -3 -4 等等加一个群 谁想吃饭就 通知一下 类图 代码 角色 …

【ROS 2 Humble】 Ubuntu 20.04(Focal)平台 源码安装

提问链接&#xff1a; https://answers.ros.org/questions/ —————————————— ROS 1 各版本支持截止时间查看 ROS 1 支持时间查看 链接 https://wiki.ros.org/Distributions ROS 2 各版本支持截止时间查看 ROS 2 版本支持时间查看 ROS 2 https://docs.ros.…

element-ui中表格树类型数据的显示

项目场景&#xff1a; 1&#xff1a;非懒加载的情况 1&#xff1a;效果展示 2&#xff1a;问题描述以及解决 1&#xff1a;图片展示 2&#xff1a;html <-- default-expand-all 代表默认展开 如果不展开删除就行 --> <el-tableref"refsTable"v-loadin…

高速DSP系统设计参考指南(六)锁相环(PLL)

&#xff08;六&#xff09;锁相环&#xff08;PLL&#xff09; 1.模拟锁相环2.数字锁相环3.PLL隔离技术 系统设计人员需要隔离PLL&#xff0c;使其免受内部和外部噪声的影响。PLL通常用作频率合成器&#xff0c;将输入时钟乘以一个整数。该整数是反馈计数器M除以输入计数器N的…

Pytorch搭建DTLN降噪算法

前面介绍了几种轻量级网路结构的降噪做法&#xff0c;本文介绍DTLN—一种时频双核心网络降噪做法。 AI-GruNet降噪算法 AI-CGNet降噪算法 AI-FGNet降噪算法 Pytorch搭建实虚部重建AI-GruNet降噪算法 一、模型结构 DTLN来自[2005.07551] Dual-Signal Transformation LSTM N…