1

情况:我有一个 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’

有没有办法解决这些问题?我明白为什么会发生错误。如何定义两个类而不将它们包含在彼此的文件中?这些问题的出现是因为场试图访问粒子的成员,而粒子包含场向量。

编辑:一种解决方法是将类合并到一个文件中的一个类中……但这很荒谬,并导致各种其他问题。

EDIT2:我知道头卫。

4

2 回答 2

1

我会让 field.hpp 包含particle.hpp,在particle.hpp 中包含ElementaryField 的前向声明-然后在您的particle.cpp 中包含field.hpp。只要您在particle.hpp中没有任何代码,那应该可以解决您的问题。从技术上讲,您可以在 .hpp 中对每个进行前向声明,然后在 .cpp 中包含其他的 .hpp。这可能会更好,因为它更加标准化。我进行了最初的评估,因为你说场访问粒子的成员,而粒子只包含场向量。

另外,如果您不使用 pragma #once,也许会有所帮助?

于 2013-02-27T17:37:09.790 回答
0

大多数程序员在定义头文件时都使用包含保护。一些编译器允许

#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 中,它可以包含两个标头并具有两个对象的完整定义。只用指针和引用保持你的标题抽象,你应该没问题。

于 2013-02-27T17:56:00.520 回答