1

状況:ParticleクラスとFieldクラスがあります。パーティクルにはフィールドが関連付けられており、その逆のフィールドには多くの場合パーティクルがあります。

#include "particle.hpp"にいると入れませ"field.hpp"ん。もちろん、これは理にかなっています。#include "field.hpp""particle.hpp"

2つのファイルのそれぞれで前方宣言を使用することにしましたが、コンパイラーは次のエラーでコンパイルに失敗します。

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つの回避策は、クラスを1つのファイルの1つのクラスにマージすることです...しかし、それはばかげており、他のあらゆる種類の問題につながります。

EDIT2:ヘッダーガードについて知っています。

4

2 に答える 2

1

field.hppにparticle.hppをインクルードし、ElementaryFieldの前方宣言をparticle.hppにインクルードし、次にfield.hppをparticle.cppにインクルードします。particle.hppにコードがない限り、これで問題は解決するはずです。技術的には、.hppでそれぞれの前方宣言を実行してから、他の.hppを.cppに含めることができます。より標準化されているので、これはより良いかもしれません。フィールドはパーティクルのメンバーにアクセスしますが、パーティクルにはフィールドのベクトルが含まれているだけだとおっしゃっていたので、最初の評価を行いました。

また、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 に答える