0

我正在尝试使 MainScheduler 的方法 addJob 成为 Job 类的友元函数,如下所示:

#include "MainScheduler.h"
//forward declaration
class MainScheduler;

class Job:
{
    friend void MainScheduler::addJob( Job* const job );
    ...
}

但我不断收到错误

错误 C2027:使用未定义类型“MainScheduler”

你知道我为什么会收到这条消息,我该如何解决?

4

2 回答 2

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()is afriend ofBB::g()is Aafriend of 之类的事情,所以有时你只需要满足于与整个班级交朋友。(或者有一些奇特的方法可以使用帮助类来请求/授予某些函数集的权限,但是当您需要可扩展的库接口时,这会更有帮助。)

于 2012-06-02T17:06:25.970 回答
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
  • 预处理器包括 Job.h
  • 因为MAINSCHEDULER已经定义,所以它跳过 MainScheduler.h 的包含
  • 它包括来自的令牌Job
  • 包括 Job.h 结束
  • 它包括来自的令牌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

};

通过与全班同学交朋友,您只需提前声明即可逃脱并打破循环。

于 2012-06-02T17:21:34.917 回答