4

我有两个类,它们都使用其他类,例如:

// class1.h
class Class1;
#include "class2.h"

class Class1 {
  public:
  static Class2 *C2;
  ...
};

// class2.h
class Class2;
#include "class1.h"

class Class2 {
  public:
  static Class1 *C1;
  ...
};

当我像上面的例子一样定义它时,它可以工作(我也有一些#ifndef可以避免无限的标题重复)。但我也想在我的类中添加一些内联函数。我在这里读到我应该将内联函数的定义放在头文件中,因为如果我将它们放在 cpp 文件中并想从其他 cpp 文件中调用它们,它将不起作用(当我这样做时,我在链接)。但这里的问题是这样的:

// class1.h
...
inline void Class1::Foo() {
  C2->Bar();
}

我收到错误:无效使用不完整类型“struct Class2”。

那么我该怎么做呢?

4

3 回答 3

8

您需要延迟包含标题,然后包含它并定义您的内联方法。通过在每个标头中执行此操作,它们是自给自足的,并且包含一个将始终包含另一个,包含保护可防止无限递归。

A.hpp

#ifndef INCLUDE_GUARD_B9392DB18D114C1B8DFFF9B6052DBDBD
#define INCLUDE_GUARD_B9392DB18D114C1B8DFFF9B6052DBDBD

struct B;

struct A {
  B* p;
  void foo();
};

#include "B.hpp"

inline
void A::foo() {
  if (p) p->bar();
}

#endif

B.hpp

#ifndef INCLUDE_GUARD_C81A5FEA876A4C6B953D1EB7A88A27C8
#define INCLUDE_GUARD_C81A5FEA876A4C6B953D1EB7A88A27C8

struct A;

struct B {
  A* p;
  void bar();
};

#include "A.hpp"

inline
void B::bar() {
  if (p) p->foo();
}

#endif
于 2010-02-09T23:02:07.153 回答
2

你把它弄混了。你想要的是:

// class1.h
class Class2;

class Class1 {
  public:
  static Class2 *C2;
  ...
};

// class2.h
class Class1;

class Class2 {
  public:
  static Class1 *C1;
  ...
};

并在源代码中包含相应的标题。该行:

class Class1; // or Class2

声明一个不完整的类型,你可以拥有指向不完整类型的指针和引用。但是,在使用时,它需要完整。所以只要说“嘿,它会存在的!” 在标题中,并在源代码中告诉它它是什么。

于 2010-02-09T23:00:12.943 回答
0

我的建议是您将常用方法和成员放入基类,然后从基类派生 C1 和 C2。这可能会解决循环依赖问题。

于 2010-02-10T18:09:28.617 回答