1

重複の可能性:
なぜこれで複数の関数宣言が妨げられないのですか?

Global.h

#ifndef Global_h
#define Global_h

#include <iostream>

unsigned char exitStatus;

#endif

OutputHandler.h

#ifndef OutputHandler_h
#define OutputHandler_h

#include "Global.h"

class OutputHandler {
private:
    static bool instanceExists;
// more code  

#endif

ルート.h

#ifndef Root_h
#define Root_h

// declarations

OutputHandler *output;

#endif

ルート.cpp

#include "Root.h"
// gets instance of OutputHandler
// more code

exitStatusstatic bool instanceExists、およびOutputHandler.objRoot.objによって既に定義されている静的クラス出力に関するエラーが発生しています。問題は、ヘッダーファイルOutputHandler.hをRoot.hOutputHandler.cppの両方に含めることにあると思います。これを修正する方法、またはヘッダーファイルをより適切に整理する方法を知っている人はいますか?

4

3 に答える 3

4

インクルード ガードは翻訳単位レベルでのみ機能するためです (この単純なケースでは、単一の C ファイルを翻訳単位と見なすことができます)。

つまり、単一の C ファイルがヘッダー ファイルを 2 回インクルードする場合、インクルード ガードにより 2 回目は処理されません。

ただし、2 つの異なるC ファイルからヘッダーをインクルードすると、それぞれがそのヘッダーで定義された変数のコピーを取得します。

次に、それらをリンクすると、重複が得られます。

この問題を回避する最も簡単な方法は、ヘッダーで何かを定義せず、宣言するだけです。

したがって、ヘッダー (例: xyzzy.h) には次のように記述します。

extern int xyzzy;  // declare but don't define.

そして、それを使用したいすべての C ファイルに、次のように入力します。

$include "xyzzy.h"

そして、それらの C ファイルの1 つに、以下も入れます。

int xyzzy;        // define it here, once.

宣言は単純な「これがここではなく、どこかに存在することを宣言する」と考えることができますが、定義は「私はこれを今ここで作成しています」と考えることができます。

于 2013-02-01T09:26:31.663 に答える
2

1 つの実装ファイルextern usigned char exitStatusで宣言Global.hおよび定義します。

于 2013-02-01T09:26:00.237 に答える
1

問題はリンク段階にあります。ヘッダーにガードを含めても役に立ちません。

C には、宣言定義という別個の概念があります。宣言はヘッダーに入れられるものです。それらは、特定の変数が存在することを単に述べているだけです。変数の定義は、ストレージが実際に割り当てられる場所です。

たとえば、 には次のGlobal.hものがあります。

#ifndef Global_h
#define Global_h

#include <iostream>

usigned char exitStatus;

#endif

これはと呼ばれる変数を定義exitStatusしていますが、指定された変数はプログラム内の 1 か所でのみ定義する必要があるため、リンカは不平を言っています。ヘッダーで宣言し、ソース (*.cpp) ファイルの 1 か所だけで定義する必要があります。たとえば、ヘッダーでexitStatus を次のように宣言する必要があります。

extern char exitStatus;

1 つのソース ファイルのみで、次のように定義します。

char exitStatus;

ヘッダー ファイル内で変数を宣言する必要がある他の場所と同様に、 outputinの状況も同様です。Root.h

参照: http://www.cprogramming.com/declare_vs_define.html

于 2013-02-01T09:28:42.827 に答える