我遇到了包含模板实现模型和* .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
答案 0 :(得分:1)
A.hpp和A1.h不应包括与B或C相关的任何内容。
答案 1 :(得分:1)
为什么A
的实施需要了解B
&amp; C
一点都没有?如果父级的实现依赖于特定子级的详细信息,则似乎未正确使用继承。
您似乎可以删除这些包含并以这种方式解决问题。
您能否具体说明为什么需要加入B
&amp; C
标题/实现中的A
?
答案 2 :(得分:1)
你需要:
如果您执行上述所有操作,您将允许其他代码以任何顺序包含标题,但它们仍将以“循环”方式工作。没有我的拼写检查器不知道那个词,因为我刚刚完成了。
换句话说,你需要做这样的事情:
<强> 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 */