コメントでCsaba Tothに同意します。これはぐちゃぐちゃなので、きちんと掃除する必要があります。あなたをプロジェクトに参加させてくれた人たちに、時間をかけて適切なヘッダーとソース ファイルで書き直す価値があることを納得させてください。大量の開発とサポートを節約し、顧客が発見する前にバグを明らかにするのに役立ちます。
そうは言っても、extern を処理する必要があります。
あなたの選択 1 は非常に悪いです。.cpp には、別の .cpp を含めることはできません。大量の「定義済み」エラーが発生しないのは、奇跡にはほど遠いです。
選択肢 2 は、ファイル B で別の静的な int を定義しています。これは、ファイル C の int とは別の int になり、異なる値を持つことができます。
あなたがする必要があるのは、ファイル C の int を として宣言することですextern
。ヘッダーまたは cpp のいずれかで実行できます。秘訣は、それが 1 か所でのみインスタンス化されるようにすることです。
したがって、B の一部で、次のようにします。
extern int dog;
dog
これにより、プログラムの実行準備が整うまでにint が呼び出されることがコンパイラに通知されます。次に、リンカーはその変数の唯一無二のインスタンス (現在は fileC.cpp に存在する) を探し、すべてを同じ場所にポイントします。
同じ名前のグローバル スコープ変数が 2 つあるため、選択肢 3 では問題が発生していました。を使えextern
ば解決します。
一般的に、適切なコーディング構造は次のとおりです。
ヘッダファイル
- .h が複数回含まれないようにするために、ラッパーがあるか、サポートされている場合
#ifdef MYFILE_H
は必ずラッパーを用意してください。#pragma once
- 関数宣言だけを入れてください - どうしてもインラインにする必要がない限り、実装はほとんどないはずです (最近の優れたコンパイラは、ほとんどの状況で独自に最適化できます)。実装するすべての関数がそのファイルの内部にのみ存在し、他のファイルに依存しないようにする必要があります。
- を使用して、他のファイル グローバル変数を参照できます
extern
。
Cpp ファイル
最もクリーンなのは、ヘッダーから実装を一致させることですが、コンパイラとリンカーを使用すると、どこにでも何でも実装できます。従うべき主な規則は、各関数と各 extern をすべてのコードで 1 回だけ実装することです。function を持つ場所は 1 つだけであり、代わりにmyFunc
を宣言する場所は 1 つだけであるべきです。関数宣言と変数の両方がコンパイラに「これについて心配する必要はありません。完了したことを確認します」と伝え、リンカはすべてのオブジェクトの中からそれを探します。int dog
extern int dog
extern
選択 1 と選択 2 でエラーに言及しなかったという事実から、コンパイルまでは行ったものの、リンカを実行したことがないと推測しています。次に推測するのは、Visual Studio が両方のステップを一度に処理するため、これは UNIX システムであるということです。その場合、make
ビルドなどを処理するシステムが必要です。3 つの選択肢すべてでエラーが発生するはずです。