由于嵌套,不能使用#include,不能使用类原型

Cannot #include due to nesting, cannot use class prototype

本文关键字:不能 #include 原型 于嵌套 嵌套      更新时间:2023-10-16

情况:我有一个Particle类和一个Field类。粒子有与之相关联的场,反之亦然。

我不能在"field.hpp"#include "particle.hpp",如果我在"particle.hpp"#include "field.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’

有解决这些问题的方法吗?我理解错误发生的原因。如何定义这两个类而不将它们包含在彼此的文件中?这些问题的出现是因为field试图访问particle的成员,而particle包含了一个由场组成的向量。

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

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

另外,如果你不使用pragma #一次,也许它会有所帮助?

大多数程序员在定义头文件时使用include保护符。有些编译器允许

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