我正在尝试将MainScheduler的方法addJob作为Job类的友元函数,如下所示:
#include "MainScheduler.h"
//forward declaration
class MainScheduler;
class Job:
{
friend void MainScheduler::addJob( Job* const job );
...
}
但我一直收到错误
错误C2027:使用未定义类型'MainScheduler'
你知道我为什么收到这条消息,我该如何解决?
答案 0 :(得分:5)
您只能命名已声明的成员函数,即使是友情声明也是如此。这意味着必须定义类,而不仅仅是前向声明。
错:
class X;
class Y
{
friend void X::f(); // ERROR
};
右:
class X
{
public:
void f();
};
class Y
{
friend void X::f();
};
为什么#include "MainScheduler.h"
没有明确class MainScheduler
的定义,这是不明显的,所以还有其他奇怪的事情发生在那里。
此规则意味着无法执行A::f()
是B
的朋友而B::g()
的朋友是A
的朋友,所以有时你只需要满足于整个班级的朋友。 (或者有一些奇特的方法可以使用辅助类来请求/授予某些函数集的权限,但是当你需要一个可扩展的库接口时,这会更有用。)
答案 1 :(得分:2)
问题很简单:你不能有依赖循环。
// MainScheduler.h
#ifndef MAINSCHEDULER
#define MAINSCHEDULER
#include "Job.h"
class MainScheduler { friend class Job; };
#endif
// Job.h
#ifndef JOB
#define JOB
#include "MainScheduler.h"
class Job { friend class MainScheduler; };
#endif
解析MainScheduler.h时会发生以下情况:
MAINSCHEDULER
未定义,因此解析开始MAINSCHEDULER
MAINSCHEDULER
已经定义,所以它会跳过包含MainScheduler.h Job
MainScheduler
这会产生以下预处理器输出,编译器会看到:
// ignored #include "MainScheduler.h"
class Job { friend class MainScheduler; };
class MainScheduler { friend class Job; };
这就是为什么在你引入前向声明之前,编译器在MainScheduler
的定义中抱怨了未知的Job
符号。
您的标题不能包含在一个循环中,并且您不能仅使用前向声明与成员函数成为朋友。
我建议你将Job.h重写为:
class MainScheduler; // forward declaration
class Job {
friend class MainScheduler;
public:
// whatever
};
通过与全班同学,你只需要一个前瞻宣言就可以逃脱,并打破这个循环。