【C++】友元函数、友元类、内部类

2023-11-01

一、友元函数

友元函数是定义在类外的普通函数,但是可以访问类的所有成员,包括私有和保护成员。

它不是类的成员函数,但是要在类里声明。

例子:

class A
{
	// 友元函数可以在类中任何地方声明,不受访问限定符限制
	friend void print();
	
public:
	...

private:
	int a;
	int b;
	int c;
};

// 友元函数是定义在类外的普通函数
// 但是可以访问类的私有和保护成员
void print()
{
	cout << a << ' ' << b << ' ' << c << endl;
}

注意,一个函数可以是多个类的友元函数,只要在每个类中声明友元函数即可。

二、友元类

如果 A 是 B 的友元类,则在 A 中可以访问 B 的所有成员,包括私有和保护成员。

前提是要在 B 里声明 A 是 B 的友元类。声明方式与友元函数类似,可以在类中任何地方声明,不受访问限定符限制。

例子:

class B
{
	// 友元类可以在类中任何地方声明,不受访问限定符限制
	friend class A;
	
public:
	...
	
private:
	int x;
	int y;
	int z;
};

class A
{
public:
	// 声明了友元类,在 A中就可以访问 B的私有和保护成员
	void func(B& d)
	{
		d.x = 1;
		d.y = 2;
		...
	}
	
private:
	...
};

注意,友元关系是单向的,而且不能传递、不能继承。

单向:比如上面的例子中,A 是 B 的友元类,但是 B 不是 A 的友元类,B 中不能访问 A 的非公有成员,除非也在 A 中声明 B 是 A 的友元类。

不能传递:比如 A 是 B 的友元类,B 是 C 的友元类,但是不能推出 A 是 C 的友元类。

不能继承:to be continued…

三、内部类

在一个类里声明的另一个类,叫作内部类。

内部类可以访问外部类的所有成员,包括私有成员和保护成员。但是外部类不能访问内部类的非公有成员。

例子:

class A 
{
public:
	// B是 A的内部类
    class B 
    {
    public:
    	// B中可以访问 A的所有成员
        void func(A& d) 
        {
            d.x = 1;
            d.y = 0;
        }
    };
private:
    int x;
    int y;
};

事实上,内部类就是外部类的友元类,它们是两个独立的类。

但是创建内部类的对象时,需要这样表示:外部类名::内部类名 对象名

例子:

class OuterClass 
{
public:
    class InnerClass 
    {
    public:
        void display() 
        {
            cout << "Inner Class" << endl;
        }
    };
};

int main() 
{
    OuterClass::InnerClass innerObj;//创建内部类的对象

    innerObj.display();

    return 0;
}

内部类可以在外部类的任意位置声明,但是与友元类声明不同的是,内部类会受访问限定符的限制。

四、小结

友元提供了一种突破封装的方式,有时可以提供便利。

但是友元会增加类与类之间的耦合度,不宜多用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【C++】友元函数、友元类、内部类 的相关文章

  • C# 打印问题(RichTextBox)

    我想打印我的 RichTextBox eintragRichTextBox 的内容 我现在有这个代码 private void druckenPictureBox Click object sender EventArgs e PrintD
  • 在路由mvc 4中添加公司名称

    我一直在尝试为 Facebook 等用户提供在 URL 中添加公司名称的选项 http localhost 50753 MyCompany Login 我尝试过不同的网址 但没有成功 routes MapRoute name Default
  • 如何在另一个应用程序中挂钩 api 调用

    我正在尝试挂钩另一个应用程序的 ExtTextOut 和 DrawTextExt GDI 方法调用 我知道我需要使用 GetProcAddress 来查找 gdi32 dll 中那些方法的地址 并用我的函数的地址覆盖我想要挂钩的进程中的地址
  • C++ 长 switch 语句还是用地图查找?

    在我的 C 应用程序中 我有一些值充当代表其他值的代码 为了翻译代码 我一直在争论使用 switch 语句还是 stl 映射 开关看起来像这样 int code int value switch code case 1 value 10 b
  • 将完整模板参数值映射到原始类型

    我想将数字映射到类型 在这个例子中 我将创建一个函数 将 sizeof 结果映射到有符号的原始类型 我想知道是否有更好的方法来完成我在现代 C 中所做的事情 即采用模板化值并将其转换为类型 现在 这可以将大小转换为已知类型 但我似乎无法在标
  • 解析 JWT 令牌以仅获取有效负载内容,无需 C# 或 Blazor 中的外部库

    我正在使用 Blazor 编写可以访问 JWT 的客户端应用程序 我想知道一种简单的方法来读取令牌有效负载内容而不添加额外的依赖项 因为我不需要其他信息 也不需要验证令牌 我认为解析有效负载内容应该足够简单 只需将其写入方法即可 JwtTo
  • 从代码中,如何创建对存储在附加属性中的对象的属性的绑定?

    我们有一个继承的附加属性来存储一个对象 在可视化树的更下方 我们希望从代码绑定到该对象的属性 通常我们像这样构建绑定的路径部分 var someBinding new Binding Path new PropertyPath Attach
  • 如何使用 SOAP 且不使用 WSE 在 .NET 中签署 Amazon Web 服务请求

    亚马逊产品广告 API 以前称为 Amazon Associates Web Service 或 Amazon AWS 实施了一项新规则 即自 2009 年 8 月 15 日起 向其发送的所有 Web 服务请求都必须经过签名 他们在其网站上
  • 是否存在指向不同类型的指针具有不同大小的平台?

    C 标准允许指向不同类型的指针具有不同的大小 例如sizeof char sizeof int 是允许的 但是 它确实要求如果将指针转换为void 然后转换回其原始类型 它必须与其原始值进行比较 因此 从逻辑上来说 sizeof void
  • C# 开源 NMEA 解析器 [已关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找 C 开源 NMEA 解析器 嗯 我自己也不熟悉 但是一些快速搜索显示了一个代码项目 htt
  • 将接口转换为其具体实现对象,反之亦然?

    在 C 中 当我有一个接口和几个具体实现时 我可以将接口强制转换为具体类型 还是将具体类型强制转换为接口 这种情况下的规则是什么 Java 和 C 中都允许这两个方向 向下转型需要显式转型 如果对象类型不正确 可能会抛出异常 然而 向上转换
  • 如何对 NServiceBus.Configure.WithWeb() 进行单元测试?

    我正在构建一个 WCF 服务 该服务接收外部 IP 上的请求并将其转换为通过 NServiceBus 发送的消息 我的单元测试之一调用Global Application Start 它执行应用程序的配置 然后尝试将 Web 服务解析为 验
  • C#6 中的长字符串插值行

    我发现 虽然字符串插值在应用于现有代码库的字符串 Format 调用时非常好 但考虑到通常首选的列限制 字符串对于单行来说很快就会变得太长 特别是当被插值的表达式很复杂时 使用格式字符串 您将获得一个可以拆分为多行的变量列表 var str
  • 析构函数中的异步操作

    尝试在类析构函数中运行异步操作失败 这是代码 public class Executor public static void Main var c1 new Class1 c1 DoSomething public class Class
  • Project Euler #8,我不明白我哪里出了问题[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我正在做项目欧拉第八题 https projecteuler net problem 8 其中我得到了这个大得离谱的数字 7316
  • 在 OpenGL 中渲染纹理 1 到 1

    所以我想做的是使用 OpenGL 和 C 将纹理渲染到平面上 作为显示图像的一种方式 但是我需要确保在渲染纹理时没有对纹理进行任何处理 抗锯齿 插值 平滑 模糊等 这是 OpenGL 处理渲染纹理的默认方式吗 或者是否需要设置一些标志才能禁
  • ASP.NET MVC 路由:如何从 URL 中省略“索引”

    我有一个名为 StuffController 的控制器 具有无参数索引操作 我希望从表单中的 URL 调用此操作mysite com stuff 我的控制器定义为 public class StuffController BaseContr
  • 选择查询不适用于使用Parameters.AddWithValue 的参数

    C 中的以下查询不起作用 但我看不出问题所在 string Getquery select from user tbl where emp id emp id and birthdate birthdate cmdR Parameters
  • CUDA 8 编译错误 -std=gnu++11

    我正在尝试转换一些代码以使用 CUDA 并且我认为我遇到了兼容性问题 我们使用CMake 这些是我使用的 gcc 和 CUDA 版本 gcc version gcc Ubuntu 5 4 0 6ubuntu1 16 04 5 5 4 0 2
  • 来自 3rd 方库的链接器错误 LNK2019

    我正在将旧的 vc 6 0 应用程序移植到 vs2005 我收到以下链接器错误 我花了几天时间试图找到解决方案 错误LNK2019 无法解析的外部符号 imp 创建AwnService 52 在函数 public int thiscall

随机推荐

  • Quartz 环境搭建并启动

    项目代码 https github com yuleiqq quartz example tree master quartz study 1 利用IDEA 工具搭建一个基本的Java Maven 工程 并配置依赖包 pom xml 配置
  • USB-IF BC1.2充电协议解读

    BC1 2是USB2 0开始的一个使用Vbus 5V进行USB对接充电的一个协议 该协议由USB IF协会在2010年10月发布 基于当时USB 2 0的Vbus供电 最大能供给电流为500mA 协议通过USB的D D 完成并确定支持BC1
  • Flask进阶(一)——请求上下文和应用上下文完全解答(上)

    前言 flask的轻便和强大的扩展性能会让web的初级开发者甚至是有经验的开发者神往 flask能在短时间内快速搭建web的后台 而 flask web开发 基于python的web应用开发实战 是最好的flask入门教程了 但当中对应用上
  • Linux如何强制关闭PyCharm或者其他软件

    1 右键选择打开终端 2 输入ps ef指令查询所要关闭程序的PID号 3 找到自己想要关闭的程序 一定看好是自己的 别关了别人的 记住PID号 26252 26257 4 输入 kill s 9 PID号 26252 26257 5 敲上
  • Laravel 添加自定义全局函数

    第一步 在app目录下建立Common文件夹 在文件夹中创建helpers php 第二步 在根目录下的artisan文件中中引入require once DIR app Common helpers php 自动加载 第三步 在publi
  • Android开发:实现APP自动填写注册验证码功能

    http blog csdn net xiong it article details 50997084 前言 此技术的实现原理是 广播接收者 和 内容观察者 利用接收到短信时的系统发出的广播进行短信的读取 并利用正则表达式解析出短信中的验
  • 柔性数组 +结构体中数组名与指针的区别

    柔性数组 一 柔性数组 1 柔性数组的特点 2 柔性数组的使用 3 柔性数组的替代形式 二 结构体中数组名与指针的区别 一 柔性数组 柔性数组是指在结构体中定义一个为指定大小的数组 1 柔性数组的特点 1 在结构体中 柔性数组的前面至少有一
  • WSL2+ubuntu2004+cuda11.8+cudnn8.8开发环境搭建

    文章目录 1 系统环境要求 2 WSL2操作 大多是命令行 2 1 安装wsl 2 2 建议直接将默认版本设置为WSL 2 但可能不做这一步默认也是2 2 3 检查版本或状态信息 2 4 安装Linux子系统 2 5 修改安装位置 2 6
  • Eureka Client Instance status DOWN - SpringCloud Eureka 实例状态为DOWN时如何排查问题

    Eureka Client Instance status DOWN SpringCloud Eureka 实例状态为DOWN时如何排查问题 Eureka Client Instance status DOWN SpringCloud Eu
  • ios 手机浏览器,点击输入框页面会放大

    一个普通的h5静态页面 在ios手机上用浏览器打开 发现每次聚焦输入框的时候整个页面都会放大 解决办法在html的头部meta标签中设置 user scalable no viewport meta 标记 HTML 超文本标记语言 MDN
  • C++STL之List容器

    C STL之List容器 1 再谈链表 List链表的概念再度出现了 作为线性表的一员 C 的STL提供了快速进行构建的方法 为此 在前文的基础上通过STL进行直接使用 这对于程序设计中快速构建原型是相当有必要的 这里的STL链表是单链表的
  • 【Linux】进程间通信(无名/有名管道及System V共享内存)

    需要云服务器等云产品来学习Linux的同学可以移步 gt 腾讯云 lt gt 阿里云 lt gt 华为云 lt 官网 轻量型云服务器低至112元 年 新用户首次下单享超低折扣 目录 一 通信的相关概念 二 管道 半双工 1 管道的概念 三
  • vue-router学习总结

    vue router学习 vue router介绍 vue router借鉴了react router和ui router中所有的优点 官方文档 https router vuejs org 路由的快速开始 定义各页面容器组件 定义路由配置
  • Git把本地内容push到远程仓库

    第一次提交本地项目代码到github仓库 一 所需的命令 git init 1 初始化项目文件夹 git add 2 将所有文件添加到暂存区 git commit m first commit 3 提交到本地仓库 双引号内是提交的备注信息
  • 【已解决】libcef.dll怎么修复?libcef.dll丢失怎么办电脑上总显示

    libcef dll怎么修复 libcef dll丢失怎么办电脑上总显示 我们在日常使用电脑的时候 有些情况下可能会遇到出现提示计算机丢失libcef dll文件的情况 对于这种问题小编觉得我们可以先尝试使用第三方软件进行扫描下载 或者还可
  • Typescript学习(1)

    安装typescript 查看本机是否安装了node npm install g typescript 全局安装typescript tsc v 查看安装的typescript版本 使用vs code新建一个文件夹 进入该文件夹创建一个te
  • 为什么Collection不从Clone和Serializable接口继承

    Collection表示一个集合 包含了一组对象 如何存储和维护这些对象是由具体实现来决定的 因为集合的具体形式多种多样 例如list允许重复 set则不允许 而克隆 clone 和序列化 serializable 只对于具体的实体 对象有
  • Halcon和Opencv 的区别

    点击上方 小白学视觉 选择加 星标 或 置顶 重磅干货 第一时间送达 OpenCV Halcon 开发语言 C C emgu Python Ruby MATLAB等语言 C C C Visual basic和Delphi等语言 应用场合 侧
  • 使用若依分离版实现Excel导入功能

    使用若依分离版实现导入功能 1 后台代码 controller层 导入学生数据 下载模板 GetMapping importTemplate ResponseBody public AjaxResult importTemplate Exc
  • 【C++】友元函数、友元类、内部类

    文章目录 一 友元函数 二 友元类 三 内部类 四 小结 一 友元函数 友元函数是定义在类外的普通函数 但是可以访问类的所有成员 包括私有和保护成员 它不是类的成员函数 但是要在类里声明 例子 class A 友元函数可以在类中任何地方声明