是的,这个问题话题已经讨论过很多次了。我几乎很清楚其中的区别。我只有一个与书中示例相关的疑问。
这个问题与我之前的问题 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
.
我上一个问题中链接的问题很好地描述了这一点。但只是在上述情况下不起作用,所以我再次询问。