【问题标题】:Cyclic dependency, headers and templates循环依赖、标头和模板
【发布时间】:2011-02-03 17:29:12
【问题描述】:

我在模板实现的包含模型和 *.h 和 *.hpp 文件的循环依赖方面遇到问题。

让我们想象以下类的继承序列:

 A->B->C, 
 A->A1,
 B->B1, C->C1

其中 A、A1 是抽象类。

A.h(抽象类)

#ifndef A_H
#define A_H

template <class A>
{
  //some code
  virtual A() = 0;
};

#include "A.hpp"

#endif

A.hpp

#ifndef A_HPP
#define A_HPP
#include "B.h" //Circular dependency
#include "C.h" //Circular dependency

void create Object(A ** a, unsigned int code)
{
  switch (code)
  {
    case 0: *a = new B(); break;
    case 1: *a = new C();

  };
}

#endif

B.h

#ifndef B_H
#define B_H

#include "A.h"

template <class T>
class B : public A <T>
{
  //Some code
};

C.h

#ifndef C_H
#define C_H

#include "C.h"

template <class T>
class C : public B <T>
{
  //Some code
};

A1.h(抽象类)

#ifndef A1_H
#define A1_H

#include "A.h"

template <class T>
class A1 : public A <T>
{
  //Some code
};

#include "A.hpp"

#endif

A1.hpp

#ifndef A1_HPP
#define A1_HPP
#include "B1.h" //Circular dependency
#include "C1.h" //Circular dependency

void create Object(A1 ** a1, unsigned int code)
{
  switch (code)
  {
    case 0: *a = new B1(); break;
    case 1: *a = new C1();

  };
#endif

B1.h

#ifndef B1_H
#define B1_H

#include "B.h"

template <class T>
class B1 : public B <T>
{
  //Some code
};

C1.h

#ifndef C1_H
#define C1_H

#include "C.h"

template <class T>
class C1 : public C <T>
{
  //Some code
};

如何进行合理的包含避免循环依赖?我尝试用前向声明替换包含指令,但不幸的是编译器还不够......

A.hpp

#ifndef A_HPP
#define A_HPP

template <class T>
class A;
template <class T>
class B;

//some code
#endif

1.hpp

#ifndef A1_HPP
#define A1_HPP

template <class T>
class A;
template <class T>
class B;

//some code
#endif

【问题讨论】:

  • 您应该尽可能使用前向声明,而不是包含标题。我不能说你可以在哪里用前向声明替换包含指令,而不会看到你的代码。

标签: c++ templates circular-dependency


【解决方案1】:

您需要:

  1. 在其标题中定义每个类
  2. 让每个标头都包含它需要的依赖项
  3. 不**要求**依赖成功定义类,并前向声明它。

如果您执行上述所有操作,您将允许其他代码以任何顺序包含标题,但它们仍将以其“循环性”工作。不,我的拼写检查器不知道那个词,因为我只是编造的。

换句话说,你需要做这样的事情:

foo.h:

#ifndef FOO_H #define FOO_H #include "bar.h" 类吧; // 这是关键线 类富 { // ... 使用条形图 } #endif /* FOO_H */

bar.h

#ifndef BAR_H #define BAR_H #include "foo.h" 类吧; // 这是关键线 类栏{ // ... 使用 foo } #endif /* BAR_H */

【讨论】:

    【解决方案2】:

    A.hpp 和 A1.h 不应包含与 B 或 C 相关的任何内容。

    【讨论】:

      【解决方案3】:

      为什么A 的实现需要知道BC?如果父级的实现依赖于特定子级的详细信息,则似乎没有正确使用继承。

      您似乎可以删除这些包含并以这种方式解决问题。

      您能否具体告诉我们为什么需要在A 的标头/实现中包含BC

      【讨论】:

      • 我更新了源代码,请看上面。在抽象类 A 和 A1 中,我需要创建新对象...
      猜你喜欢
      • 1970-01-01
      • 2012-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多