循环依赖、标头和模板
我在模板实现的包含模型以及 *.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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您需要:
如果您执行上述所有操作,您将允许其他代码以任何顺序包含标头,但它们仍然会以“循环”方式工作。不,我的拼写检查器不知道这个词,因为我只是编造的。
换句话说,您需要执行以下操作:
foo.h:
bar.h
You'll need to:
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:
bar.h
A.hpp 和 A1.h 不应包含与 B 或 C 相关的任何内容。
A.hpp and A1.h should not include anything related to B or C.
为什么
A
的实现需要了解B
&C
根本吗?如果父级的实现取决于特定子级的详细信息,则继承似乎没有得到正确使用。您似乎可以删除这些包含内容并以这种方式解决问题。
您能否具体向我们展示为什么需要包含
B
&A
的标头/实现中的C
?Why does
A
's implementation need to know aboutB
&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
withinA
's header/implementation?