Friend 类或 Friend 成员函数 - 前向声明和标头包含

2024-02-10

是的,这个问题话题已经讨论过很多次了。我几乎很清楚其中的区别。我只有一个与书中示例相关的疑问。

这个问题与我之前的问题 https://stackoverflow.com/q/16547560/1679863,其中我以《C++ Primer》一书中的 2 个类为例。

在提到这些类时,本书引用了以下段落,特别与成员函数的声明相关WindowManager类作为友元函数。它是这样说的:

让会员功能成为朋友需要仔细构建我们的程序 适应声明和定义之间的相互依赖性。在这个 例如,我们必须按如下方式订购我们的程序:

  • 首先定义Window_mgr类,该类声明但不能定义clear。 必须先声明 Screen,然后 Clear 才能使用 Screen 的成员。
  • 接下来,定义 Screen 类,包括用于清除的友元声明。
  • 最后定义clear,现在可以引用Screen中的成员了。

我在该问题中提出的代码仅遵循此结构。但似乎并没有奏效。这让我思考上述观点是否有误导性或者我没有正确实施。

问题是,当我声明clear充当友元函数ScreenCls课堂上,我陷入循环包含头文件。我在这里再简单介绍一下这两个类的具体部分:

ScreenCls.h:

#ifndef SCREENCLS_H
#define SCREENCLS_H

#include <iostream>

#include "WindowManager.h"

using namespace std;

class ScreenCls {
    friend void WindowManager::clear(ScreenIndex);

    // Some other code
}

在这里我必须包括WindowManager.h头文件,如clear函数现在正在使用ScreenIndex在那里定义的。前向声明在这里不起作用(如果我错了,请纠正我)。

现在,接下来我们继续WindowManager.h:

#ifndef WINDOWMANAGER_H
#define WINDOWMANAGER_H

#include <iostream>
#include <vector>
#include "ScreenCls.h"

using namespace std;

class WindowManager {
public:
    // location ID for each screen on window
    using ScreenIndex = vector<ScreenCls>::size_type;

private:
    vector<ScreenCls> screens{ ScreenCls(24, 80, ' ') };
};

并集中精力声明screens这里。他们用过列表初始值设定项添加默认值ScreenCls to the vector。所以,这里我们再次需要包括WindowManager.h。现在我们进入了循环包容。这会阻止我的项目构建。

但是,如果我更改友元函数声明以使整个类成为友元,那么我可以使用forward declaring the WindowManager班级。在这种情况下,它会工作得很好。

所以,基本上友元函数在这里不起作用,但友元类正在起作用。那么,是不是上述几点执行得不好,还是我的类有问题呢?我只是想知道这个以便清楚地理解这个概念header inclusion and forward declaration.

我上一个问题中链接的问题很好地描述了这一点。但只是在上述情况下不起作用,所以我再次询问。


我猜你的问题是屏幕初始化程序。您无法初始化类内 *.h 文件中的任何数据。所以,我建议你做这样的事情:

#ifndef WINDOWMANAGER_H
#define WINDOWMANAGER_H

#include <iostream>
#include <vector>
//#include "ScreenCls.h"

using namespace std;
class ScreenCls;

class WindowManager {
public:
    // location ID for each screen on window
    using ScreenIndex = vector<ScreenCls>::size_type;

private:
    vector<ScreenCls> screens; //{ ScreenCls(24, 80, ' ') };    remove this
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Friend 类或 Friend 成员函数 - 前向声明和标头包含 的相关文章

  • CLR 2.0 与 4.0 性能比较?

    如果在 CLR 4 0 下运行 为 CLR 2 0 编译的 NET 程序会运行得更快吗 应用程序配置
  • 使用 lambda 表达式注册类型

    我想知道如何在 UnityContainer 中实现这样的功能 container RegisterType
  • 如何捕获未发送到 stdout 的命令行文本?

    我在项目中使用 LAME 命令行 mp3 编码器 我希望能够看到某人正在使用什么版本 如果我只执行 LAME exe 而不带参数 我会得到 例如 C LAME gt LAME exe LAME 32 bits version 3 98 2
  • 为什么pow函数比简单运算慢?

    从我的一个朋友那里 我听说 pow 函数比简单地将底数乘以它的指数的等价函数要慢 例如 据他介绍 include
  • IdentityServer 4 对它的工作原理感到困惑

    我阅读和观看了很多有关 Identity Server 4 的内容 但我仍然对它有点困惑 因为似乎有很多移动部件 我现在明白这是一个单独的项目 它处理用户身份验证 我仍然不明白的是用户如何注册它 谁存储用户名 密码 我打算进行此设置 Rea
  • 查看 NuGet 包依赖关系层次结构

    有没有一种方法 文本或图形 来查看 NuGet 包之间的依赖关系层次结构 如果您使用的是新的 csproj 您可以在此处获取所有依赖项 在项目构建后 项目目录 obj project assets json
  • Visual Studio 在构建后显示假错误

    我使用的是 Visual Studio 2017 构建后 sln在调试模式下 我收到错误 但是 当我通过双击错误列表选项卡中的错误来访问错误时 错误会从页面中消失 并且错误数量也会减少 我不太确定这种行为以及为什么会发生这种情况 有超过 2
  • File.AppendText 尝试写入错误的位置

    我有一个 C 控制台应用程序 它作为 Windows 任务计划程序中的计划任务运行 此控制台应用程序写入日志文件 该日志文件在调试模式下运行时会创建并写入应用程序文件夹本身内的文件 但是 当它在任务计划程序中运行时 它会抛出一个错误 指出访
  • 告诉 Nancy 将枚举序列化为字符串

    Nancy 默认情况下在生成 JSON 响应时将枚举序列化为整数 我需要将枚举序列化为字符串 有一种方法可以通过创建来自定义 Nancy 的 JSON 序列化JavaScript 原始转换器 https github com NancyFx
  • 为什么可以通过ref参数修改readonly字段?

    考虑 class Foo private readonly string value public Foo Bar ref value private void Bar ref string value value hello world
  • 使用valgrind进行GDB远程调试

    如果我使用远程调试gdb我连接到gdbserver using target remote host 2345 如果我使用 valgrind 和 gdb 调试内存错误 以中断无效内存访问 我会使用 target remote vgdb 启动
  • IQueryable 单元或集成测试

    我有一个 Web api 并且公开了一个端点 如下所示 api 假期 name name 这是 Web api 的控制器 get 方法 public IQueryable
  • 为什么从字典中获取时会得到 Action<> 的克隆?

    我有以下字典 private Dictionary
  • C++ new * char 不为空

    我有一个问题 我在 ASIO 中开发服务器 数据包采用尖头字符 当我创建新字符时 例如char buffer new char 128 我必须手动将其清理为空 By for int i 0 i lt 128 i buffer i 0x00
  • 将数组作为参数传递

    如果我们修改作为方法内参数传递的数组的内容 则修改是在参数的副本而不是原始参数上完成的 因此结果不可见 当我们调用具有引用类型参数的方法时 会发生什么过程 这是我想问的代码示例 using System namespace Value Re
  • 这个可变参数模板示例有什么问题?

    基类是 include
  • 使用 C 在 OS X 中获取其他进程的 argv

    我想获得其他进程的argv 例如ps 我使用的是在 Intel 或 PowerPC 上运行的 Mac OS X 10 4 11 首先 我阅读了 ps 和 man kvm 的代码 然后编写了一些 C 代码 include
  • 如何减少具有多个单元的 PdfPTable 的内存消耗

    我正在使用 ITextSharp 创建一个 PDF 它由单个 PdfTable 组成 不幸的是 对于特定的数据集 由于创建了大量 PdfPCell 我遇到了内存不足异常 我已经分析了内存使用情况 我有近百万个单元格的 1 2 在这种情况下有
  • Objective-C / C 给出枚举默认值

    我在某处读到过关于给枚举默认值的内容 如下所示 typedef enum MarketNavigationTypeNone 0 MarketNavigationTypeHeirachy 1 MarketNavigationTypeMarke
  • 是否可以在不连接数据库的情况下检索 MetadataWorkspace?

    我正在编写一个需要遍历实体框架的测试库MetadataWorkspace对于给定的DbContext类型 但是 由于这是一个测试库 我宁愿不连接到数据库 它引入了测试环境中可能无法使用的依赖项 当我尝试获取参考时MetadataWorksp

随机推荐

  • 调试时如何跳出while循环

    在 Eclipse 中调试期间 我的代码进入了 while 循环 我不想循环直到满足条件 所以请告诉我如何在调试期间退出 while 循环 我看到 F7 在调试菜单下被禁用 请参阅此处的屏幕截图 You can select the lin
  • javascript 函数 btoa 的 C# 版本

    我需要将一些内容从 js 重新编码为 c 利用 js 中的 btoa 方法对一串 unicode 字符将它们转换为 base64 但是 据我所知 javascrpt 使用的编码与 c 中可用的所有编码不同 我需要编码完全相同 并且不会在这些
  • 如何在perl中验证数字?

    我知道有一个图书馆可以做到这一点 使用 Scalar Util qw looks like number 但我想使用 perl 正则表达式来做到这一点 我希望它适用于双数 而不仅仅是整数 所以我想要比这更好的东西 var d thanks
  • 从 OKHTTP 下载二进制文件

    我在我的 Android 应用程序中使用 OKHTTP 客户端进行网络连接 This https stackoverflow com questions 25367888 upload binary file with okhttp fro
  • Xpath获取上面的元素

    假设我有这样的结构 div class a div class b span Text Example span div div 在 xpath 中 我想检索属性 attribute 的值 因为我里面有文本 文本示例 如果我使用这个 xpa
  • 如何在VBA中实现消失动画?

    我正在尝试在 VBA 过程中测试形状上的动画效果 我已经实现了一个目标 即在主序列 定义在哪个位置Timeline 但我无法创建消失的动画 我在代码的开头检查了一些已经存在的 并且 EffectType 似乎返回与相关出现的动画相同的值 因
  • 实现永不过期的 OAuth 刷新令牌

    在 OAuth 2 的上下文中 如何处理refresh token过期 还是缺少 我使用 JSON Web 令牌 JWT 作为access token生命周期较短 20 分钟后过期 据我了解 这意味着我不必存储access token 仅验
  • 带标头的 post 请求中出现错误 411(需要长度),但标头具有 Content-Length。库卷曲

    我使用这个选项 curl easy setopt curl CURLOPT URL urlUpload curl easy setopt curl CURLOPT ERRORBUFFER errorBuffer curl easy seto
  • SQLite 自动增量不起作用

    好吧 这不是垃圾邮件 它应该很简单 我不知道为什么它不起作用 这是我的代码 gamesdatabase openOrCreateDatabase GamesDatabase MODE PRIVATE null gamesdatabase e
  • 获取数组中的所有非唯一值(即:重复/多次出现)

    我需要检查 JavaScript 数组以查看是否存在重复值 做到这一点最简单的方法是什么 我只需要找到重复的值是什么 我实际上不需要它们的索引或它们重复了多少次 我知道我可以循环遍历数组并检查所有其他值是否匹配 但似乎应该有一种更简单的方法
  • 保存和加载数据“MVVM”方式?

    我目前正在使用 Telerik 提供的一些控件开发一个 C WPF 项目 并且我尊重 MVVM 模式 包含数据的模型 将数据呈现给 View 的 ViewModel 显示数据的视图 当然 某些模型可以重用并显示在多个视图中 在我的例子中 数
  • ChangeDetectionStrategy.OnPush 的行为不符合我的预期

    我正在尝试熟悉 Angular 2ChangeDetectionStrategy OnPush性能提升 如所解释的here https blog thoughtram io angular 2016 02 22 angular 2 chan
  • 在执行之前使 CMake 打印命令

    我正在开发一个在 Linux 上使用 CMake 构建的大型 C 项目 CMake 运行正常 在模块和应用程序树中生成大量 Makefile 运行 GNUmake导致链接器错误 我怎样才能得到make在运行之前打印出确切的命令 d 选项不打
  • 使用 JPA 和 Google App Engine 更新查询

    我正在尝试更新我的实体类 但我得到 javax persistence PersistenceException Only select and delete statements are supported 当我不使用 Google 应用
  • Extjs:使用提交表单上传文件

    我正在尝试使用 ExtJs 和 Spring 上传文件 excel 但没有成功 所以我希望你能帮助我 在面板中 我有一个按钮 文件上传字段 我可以通过该按钮选择一个要上传的文件 xtype fileuploadfield buttonOnl
  • 我可以对不同的对象类型使用一个 TypeConverter 吗?

    到目前为止存储在房间数据库我一直在为每个类使用类型转换器 像这样 SerializedName sidebar Expose TypeConverters SidebarConverter class private Sidebar sid
  • 如何让 filepicker 和turbolinks 很好地协同工作?

    我使用 Rails 3 2 turbolinks 和 Filepicker io 开发一个 Web 应用程序 我像这样加载 API 密钥 coffeescript 我认为 document ready就足够了 因为文件选择器脚本在第一个请求
  • 您可以定义自己的 HTML 元素属性吗?

    我想知道您是否可以在 HTML 中定义自己的属性 例如 在 HTML div 中有一系列属性 例如style title class等等 您可以自己编写并添加自己的内容 同时保持语法正确吗 例如 div class example div
  • 当 ObservableCollection 中的模型属性发生更改时更新 UI?

    我有一个视图 其中包含从网络服务获取的一组图像 我在此类列表中收到它们 public class ImageModel public int Id get set public string Name get set public stri
  • Friend 类或 Friend 成员函数 - 前向声明和标头包含

    是的 这个问题话题已经讨论过很多次了 我几乎很清楚其中的区别 我只有一个与书中示例相关的疑问 这个问题与我之前的问题 https stackoverflow com q 16547560 1679863 其中我以 C Primer 一书中的