循环依赖、标头和模板

发布于 2024-10-15 21:56:19 字数 2087 浏览 2 评论 0原文

我在模板实现的包含模型以及 *.h 和 *.hpp 文件的循环依赖方面遇到了麻烦。

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

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

其中A、A1是抽象类。

啊(抽象类)

#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

I am having troubles with inclusion model of templates implementation and cyclic dependency of *.h and *.hpp files.

Let us imagine the following inheritance sequences of classes:

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

where A, A1 are abstract classes.

A.h (Abstract class)

#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 (abstract class)

#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
};

How to make a reasonable including to avoid the circular dependency? I try to replace include directives with forward declarations, but unfortunately it was not enough for compiler...

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

雨巷深深 2024-10-22 21:56:19

您需要:

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

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

换句话说,您需要执行以下操作:

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 */

You'll need to:

  1. Define each class in its header
  2. Have each header include the dependencies it needs
  3. Not **require** that the dependency succeed in defining the class, and forward-declare it as well.

If you do all of the above you'll allow other code to include the headers in any order but they'll still work in their "circulariness". No my spelling checker didn't know that word, as I just made it up.

In other words, you need to do things like this:

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 */
水溶 2024-10-22 21:56:19

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

A.hpp and A1.h should not include anything related to B or C.

情场扛把子 2024-10-22 21:56:19

为什么A的实现需要了解B & C 根本吗?如果父级的实现取决于特定子级的详细信息,则继承似乎没有得到正确使用。

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

您能否具体向我们展示为什么需要包含 B & A 的标头/实现中的 C

Why does A's implementation need to know about B & C at all? If the parent's implementation depends on details of a specific child, it seems like the inheritance isn't being used properly.

It seems likely you can just remove those includes and fix the problem that way.

Can you show us specifically why you need to include B & C within A's header/implementation?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文