情况:我有一个Particle类和一个Field类。粒子具有与它们相关联的场,反之亦然的场通常具有粒子。
如果我#include "particle.hpp"
"field.hpp"
,我#include "field.hpp"
"particle.hpp"
error: invalid use of incomplete type ‘class ElementaryParticle’
error: forward declaration of ‘class ElementaryParticle’
error: invalid use of incomplete type ‘class ElementaryField’
error: forward declaration of ‘class ElementaryField’
当然,这很有道理。
我使用了两个文件中的每个文件中的前向声明,但编译器现在无法使用这些错误进行编译:
{{1}}
是否有解决这些问题的工作?我理解为什么会出错。如何定义这两个类而不将它们包含在每个其他文件中?出现这些问题是因为字段尝试访问粒子的成员,而粒子包含字段向量。
编辑:一种解决方法是将类合并到一个文件中的一个类......但这将是荒谬的,并导致各种其他问题。
EDIT2:我知道头卫。
答案 0 :(得分:1)
我会使field.hpp包含particle.hpp,在particle.hpp中包含ElementaryField的前向声明 - 然后在particle.cpp中包含field.hpp。这应该可以解决您的问题,只要您在particle.hpp中没有任何代码即可。从技术上讲,你可以在.hpp中对每个进行前向声明,然后在.cpp中包含另一个.hpp。这可能会更好,因为它更标准化。因为你说该字段访问粒子成员,而粒子只包含一个字段向量,所以我选择了我的初始评估。
另外,如果您没有使用编译指示#once,也许会有用吗?
答案 1 :(得分:0)
大多数程序员在定义标题时都使用include guard。
允许一些编译器#pragma once
指令但如果不可用,则常见的约定是定义#ifndef防护,如下所示:
#ifndef PARTICLE_HPP__
#define PARTICLE_HPP__
class Field;
class Particle {
// ...
};
#endif // PARTICLE_HPP__
和
#ifndef FIELD_HPP__
#define FIELD_HPP__
class Particle;
class Field {
// ...
};
#endif // FIELD_HPP__
完成后,您现在在每个上下文中都有未定义类的问题。这里的解决方案是永远不要假设在场中定义粒子,并且从不假设粒子中场的定义。你有声明,那没关系。但是不要使用任何需要定义的东西。例如,在Particle.hpp中,避免:
Field x; // Error: Requires Constructor definition
Field *y; // Okay
Field &z; // Okay, but must be initialized in constructor
y->foo(); // Error: Requires definition of foo
z.bar; // Error: Requires definition of bar
相反,将所有这些错误位放在.cpp中,它可以包含两个标头,并具有两个对象的完整定义。
,只保留标题和引用的标题摘要。