1

我有两节课

请求管理器.h

#ifndef REQUESTMANAGER_H
#define REQUESTMANAGER_H

#include "RequestClient.h"
class RequestManager
{
public:
     void AddReqeustItem(RequestClient *req);

private:
 std::list<RequestClient*> m_reqClientContainer;
};
#endif

请求客户端.h

#ifndef REQUESTCLIENT_H
#define REQUESTCLIENT_H

class RequestManager; // Forward declaration to avoid cyclic inclusion.

class RequestClient {
public:
void CreateRequest(RequestManager* pManager)
{
  // ... I am creating a request.
  pManager->AddReqeustItem(req);
};
#endif

在上面的代码中,我在请求客户端类中收到错误未定义的 RequestManager。有什么问题,我该如何解决?

4

3 回答 3

5

您不能使用只有前向声明的类型。前向声明用于告诉编译器该类型存在但编译器不知道该类型的内容。

我的建议:

  • 在头文件中,我只会定义类和函数成员。因此,如果仅使用指针,则可以进行前向声明。
  • 在正文文件中,编写您的成员函数的代码并包含头文件
于 2012-11-28T13:20:09.880 回答
1

将成员函数定义放在#includes 两个头文件的源文件中。

或者,如果您仍然希望它是inline(或者如果它是模板化的),那么在定义所有相关代码之后,将成员函数体的定义进一步放在标题中。在单个头文件的情况下(在这里确实有意义):

class B; // forward decl
class A {
  void use(B*);
};

class B {
  void use(A*);
};

void A::use(B*b) { /* ... */ }
void B::use(A*a) { /* ... */ }

请注意,将代码拆分为文件(几个头文件和一个源代码)只是为了方便程序员(使代码的其他部分更容易维护和使用),但从编译器的角度来看,这并没有没关系:它只看到一个大代码文件(预处理后)。因此,如何将上述布局拆分为标题和源文件取决于您。

于 2012-11-28T13:18:30.230 回答
1

您使用 方法RequestManager::AddReqeustItem(),但只有 . 的前向声明RequestManager。仅通过前向声明,编译器甚至不知道 RequestManager 存在哪些方法。所以,要解决这个问题,你必须提供RequestManager的定义,通常在头文件中。

将 的方法定义移动CreateRequest()到 cpp 文件中并在其中包含 RequestManager.h

请求管理器.cpp:

#include "RequestManager.h"
...
void CreateRequest(RequestManager* pManager)
{
  // ... I am creating a request.
  pManger->AddReqeustItem( req);
}
于 2012-11-28T13:19:40.337 回答