是的,这个问题已经讨论了很多次了。我几乎很清楚其中的区别。我对书中的一个例子有一个疑问。
这个问题与我之前的问题有关,我在 C++ Primer 一书中提出了 2 个类作为示例。
关于这些类,本书引用了以下段落,特别涉及将WindowManager
类的成员函数声明为友元函数。它是这样说的:
使成员函数成为朋友需要仔细构造我们的程序以适应声明和定义之间的相互依赖关系。在这个例子中,我们必须对我们的程序进行如下排序:
- 首先,定义 Window_mgr 类,该类声明但不能定义 clear。必须先声明 Screen,clear 才能使用 Screen 的成员。
- 接下来,定义类 Screen,包括一个用于 clear 的友元声明。
- 最后定义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
为vector
. 所以,这里我们需要再次包含WindowManager.h
. 现在我们进入了循环包容。这会阻止我的项目构建。
但是,如果我更改友元函数声明以使整个类成为友元,那么我可以使用forward declaring
该类WindowManager
。在这种情况下,它会正常工作。
所以,基本上朋友功能在这里不起作用,但朋友类正在工作。那么,是上述几点在实施方面进展不顺利,还是我的课程有问题?我只是想知道这一点以清楚地理解header inclusion
and的概念forward declaration
。
我上一个问题中链接的问题很好地描述了这一点。但只是在上述情况下它不起作用,所以我再次问它。