1

「ダブルリンク」という用語を使用するのは、実際のフレーズが何であるか、または存在するかどうかがわからないためですが、次の内容の head1.h と head2.h の 2 つのヘッダーがあると仮定します。

head1.h で:

#include"head2.h"
//do stuff

head2.h で:

#include"head1.h"
//do stuff

これは実際には無限ループではなく、有限のコンピューターに無限をもたらす別の形式であるため、互いに向かい合って配置された 2 つのミラーとして視覚化します (ただし、余談になります)。ポイントは、この概念、またはこの概念のバリエーションを使用することが有用または必要な状況があるかどうかです。(つまり、goto は即興の休憩として使用できると思います)。

4

4 に答える 4

7

通常、ヘッダーにはプリプロセッサ ステートメントがあり、まさにこの種のことが無限再帰を引き起こすのを防ぎます。

#ifndef MY_FILE_H
#define MY_FILE_H

//do stuff

#endif

その保護があっても、相互インクルードは通常悪い考えです。

于 2009-05-16T22:47:01.140 に答える
3

それは「循環的インクルード」であり、いいえ、それは望ましいことではありません。goto はプログラム実行の一部であり、 #includes はコンパイルの前処理段階で解釈されるため、goto は役に立ちません。

通常は、ヘッダー ファイルを次のような構造にすることです。

#ifndef FOO_H
#define FOO_H
... rest of the include file here
#endif

そのため、同じものを 2 回定義しようとしません。

試してみると、次のようになります。

bash $ gcc crecursive.c
bh.h:1 からインクルードされたファイルで、

            from ah.h:1,  
            from bh.h:1,  
            from ah.h:1,   

... 多くの行が省略されています

            from ah.h:1,   
            from crecursive.c:2: ah.h:1:16: error: #include nested too deeply    

バッシュ $

于 2009-05-16T22:45:42.000 に答える
1

これを回避する通常の方法は、空のクラス宣言を使用することです。

//head1.h

class Foo;

class Bar {
public:
   Bar(Foo* f) : foo(f) {}
private:
   Foo* foo;
};

// head2.h

class Bar;

class Foo {
public:
    void func(Bar* bar); 
};

ヘッダー ファイルが、互いの前に宣言する必要がある多くのクラスを作成する場合、通常は のようなインクルード ファイルになります。

//fwd.h

class Bar;
class Foo;

// head1.h

#include "fwd.h"

class Foo { ....

// head2.h

#include "fwd.h"

class Bar { ....
于 2009-05-16T22:48:43.787 に答える
0

実際には無限ループではないため、2 つのミラーが互いに反対側に配置されているように視覚化します。

あなたは間違って視覚化します。;) #include は単なるコピー/貼り付けであり、プログラムがコンパイルされる前に行われることに注意してください。あなたが設定したのは、コンパイル中の無限ループです。コンパイラは、#include "head2.h" で始まる head1.h を読み取ります。したがって、head2.h を挿入して解析を続けますが、#include "head1.h" で始まるので、それを含める必要があります。

通常、これによりコンパイラが無限ループに陥るのを防ぐために、ガードを含めます。

重要なのは、これはプログラムがコンパイルされる前、そして確かに実行される前にプレーンテキスト処理として発生することです。そのため、無限の回数のコピー/貼り付けがあなたの楽しみのアイデアでない限り、実際には建設的なものに使用できるものではありません.時間。

于 2009-05-16T22:52:02.017 に答える