15

プロジェクトには2つのクラスがあります:

// mainw.h

#include "IFr.h"
...
class mainw
{
public:
static IFr ifr;
static CSize=100;
...
};

//IFr.h

#include "mainw.h"
...
class IFr
{
public float[mainw::CSize];
};

しかし、このコードをコンパイルできず、static IFr ifr;行でエラーが発生します。この種のクロスインクルージョンは禁止されていますか?

4

6 に答える 6

17

この種のクロスインクルージョンは禁止されていますか?

はい。

回避策は、mainwのifrメンバーが参照またはポインターであると言うことです。これにより、次のように、完全な宣言を含める代わりに、前方宣言が実行されます。

//#include "IFr.h" //not this
class IFr; //this instead
...
class mainw
{
public:
static IFr* ifr; //pointer; don't forget to initialize this in mainw.cpp!
static CSize=100;
...
}

または、別のヘッダーファイルでCSize値を定義します(ifr.hがmainw.hをインクルードする代わりにこの他のヘッダーファイルをインクルードできるようにします)。

于 2009-08-15T11:15:11.567 に答える
4

この方法で相互に埋め込む2つのクラスを持つことはできません。それらの1つをポインタにすることができます:

class foo;

class bar 
{
    foo* fooPtr;
}

fooを作成し、それをbarのコンストラクターでfooPtrに割り当て、デストラクタで解放する必要があります。これは間違いなくもう少し手間がかかります。

または、この場合、コメント投稿者の1人が提案したように、mainw :: sizeを定義して、どこか一般的な場所に配置します。

于 2009-08-15T11:15:16.857 に答える
1

このような再帰的なインクルードを実行できますが、一般に、ある種のヘッダーガードトリックを使用する必要があります。そうしないと、プリプロセッサが無限再帰になります。基本的に2つのクラスがあり、それぞれがコンパイルするために他方の完全な宣言を相互に確認する必要があるため、これは根本的な問題の解決には実際には役立ちません。

class mainw
{
public:
static IFr ifr; // needs to see the full declaration of the Ifr class in order to know the size
...

class IFr
{
public float[mainw::size]; // needs to see the full declaration of mainw in order to know what size is

どちらを先に置いても、もう一方の詳細を知る必要があるため、コンパイルできません。

于 2009-08-15T11:15:27.793 に答える
1

この種の循環包含はC++では許可されていませんが、これは機能するはずです。

IFr.hを含める代わりに、前方宣言を使用します。

class IFr;
class mainw
{
    //...
};

これによりmainwコンパイルは問題なく行われますが、メンバーを使用するすべてのコードifrにはIFr.hも含める必要があります。

これifrは、がstaticメンバーであるためにのみ機能します。それ以外の場合、コンパイラはの正確なサイズを知る必要がありifrます。

また、他の多くの人が言っているように、同じヘッダーを2回含めることによるエラーを回避するために、両方のヘッダーの周りにガードを含める必要があります。

#ifndef IFR_H
#define IFR_H
//...
#endif
于 2009-08-15T11:38:13.037 に答える
1

できるよ:

// mainw.h

#include "IFr.h"
class mainw {
public:
    static const size_t CSize=100;
    static IFr<CSize> ifr;
...
};

// IFr.h
template <size_t Sz>
struct IFr {
    float sz_[Sz];
};

または、実行時に CSize を変更する必要がある場合は、@ChrisW の回答が示すようにポインター ソリューションを使用します。

于 2009-08-15T11:58:27.143 に答える
0

あなたが得た場合

#ifndef __MYHEADER_NAME_WHICH_IS_RANDOM_PER_FILE_H
#define __MYHEADER_NAME_WHICH_IS_RANDOM_PER_FILE_H
//... Code..
#endif

あなたのコードをラップして、あなたは大丈夫です:)

[編集] コードのスペル :O :P

于 2009-08-15T10:58:15.517 に答える