循环依赖,标头和模板

时间:2011-02-03 17:29:12

标签: c++ templates circular-dependency

我遇到了包含模板实现模型和* .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
};

如何做出合理的包括避免循环依赖?我尝试用前向声明替换include伪指令,但不幸的是它对编译器来说还不够......

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

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

为什么A的实施需要了解B&amp; C一点都没有?如果父级的实现依赖于特定子级的详细信息,则似乎未正确使用继承。

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

您能否具体说明为什么需要加入B&amp; C标题/实现中的A

答案 2 :(得分:1)

你需要:

  1. 在其标题中定义每个类
  2. 让每个标题包含所需的依赖项
  3. 不**要求**依赖成功定义类,并向前声明它。
  4. 如果您执行上述所有操作,您将允许其他代码以任何顺序包含标题,但它们仍将以“循环”方式工作。没有我的拼写检查器不知道那个词,因为我刚刚完成了。

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

    <强> foo.h中:

      #ifndef FOO_H
      #define FOO_H
    
      #include "bar.h"
    
      class bar;       // THIS IS THE CRITICAL LINE
    
      class foo {
        // ... uses bar
      }
      #endif /* FOO_H */
    

    <强> bar.h

      #ifndef BAR_H
      #define BAR_H
    
      #include "foo.h"
    
      class bar;       // THIS IS THE CRITICAL LINE
    
      class bar {
        // ... uses foo
      }
      #endif /* BAR_H */