1

** これは大規模なプロジェクトであり、これは単なる抽象化です **

グローバル変数とグローバル関数をfileC.cppに組み込むとビルドできません。しかし、それは fileB.cpp で問題なく動作します。

3つのファイルで関数と変数を使用できるように、いくつかの組み合わせを試しました???

//fileA.cpp

#include <fileC.cpp>

extern int dog;
extern void myFunc(int junk)
{
    //some stuff
}

//fileB.cpp

//Unsure of the connections but fileA works fine with fileB    
int dog;
void myFunc(int); //no issues here

//fileC.cpp

int dog;
void myFunc(int);//causes issues with building
4

1 に答える 1

2

コメントで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 dogextern int dogextern

選択 1 と選択 2 でエラーに言及しなかったという事実から、コンパイルまでは行ったものの、リンカを実行したことがないと推測しています。次に推測するのは、Visual Studio が両方のステップを一度に処理するため、これは UNIX システムであるということです。その場合、makeビルドなどを処理するシステムが必要です。3 つの選択肢すべてでエラーが発生するはずです。

于 2013-06-13T21:57:28.533 に答える