web-dev-qa-db-ja.com

C ++でのexternの使用法

「extern」がどのように機能するのか理解できません。私はグーグルを検索しましたが、私が試みている特定の例のケースはないようです

One.hを参照するファイルmain.cppがあり、その中にLIST1という名前のリスト(100 x 100の二重配列)があるので、二重のList1 [100] [100]があります。

このリストをone.cppでどのように使用できますか?

extern double LIST1[100][100]

動かない :/

main.cpp:

#include "one.h"

extern double LIST1[100][100];

one.cpp:

void one::useList()
{
for(j = 0; j < 100; j++)
   {
     for(i = 0; i < 100; i++)
    {
         LIST1[j,i] = 0.5;
    }
 }
}

これは私が持っているものです。

私が得ているエラー:

1> main.obj:エラーLNK2001:未解決の外部シンボル "double(* LIST1)[100]"(?LIST1 @@ 3PAY0GE @ NA)

16
Lilz

名前空間スコープでの変数宣言は常に定義ですnlessそこにexternを置きます。それは単なる宣言です。

C++での重要な規則は、同じ名前のオブジェクトの複数の定義を持つことはできないということです。ヘッダーファイルにdouble LIST1[100][100];が含まれている場合、1つの翻訳単位に含まれている限り、これは機能します。ただし、ヘッダーファイルを複数の翻訳単位に含めるとすぐに、LIST1の複数の定義ができます。ルールを破った!

したがって、複数の翻訳単位からアクセス可能なグローバル変数を使用するには、ヘッダーファイルに宣言のみがあることを確認する必要があります。これはexternで行います:

extern double LIST1[100][100];

ただし、まだ定義がないため、ヘッダーを含めてこのオブジェクトを使用することはできません。このLIST1宣言は、この型の配列がどこかに存在することを示していますが、オブジェクトを作成するには実際にそれを定義する必要があります。したがって、単一の翻訳単位(通常は.cppファイルの1つ)に、以下を配置する必要があります。

double LIST1[100][100];

これで、各.cppファイルにヘッダーファイルを含めることができ、宣言のみを取得できます。プログラム全体で複数の宣言を行うことは完全に問題ありません。 .cppファイルのoneのみがこの定義を持ちます。

30

C++では、以前のCと同様に、各ソースファイルはオブジェクトファイルにコンパイルされます。次に、すべてのオブジェクトファイルがリンクされ、実行可能プログラムが作成されます。

シンボル(関数、グローバル変数)を共有するために、ファイルに対してローカルなもの、プライベートなもの、他のファイルからインポートされたものをコンパイラーに指示するキーワードがいくつかあります。

`extern 'キーワードは、シンボルにアクセスできるが、定義されていないことを意味します。他のモジュールで(グローバルとして)定義する必要があります。そうでない場合は、リンク時に「未定義のシンボル」エラーが発生します。

22
Javier