web-dev-qa-db-ja.com

C++でexternを使用する場合

私は「Think in C++」を読んでいて、それはextern宣言を導入したばかりです。例えば:

extern int x;
extern float y;

私はその意味(定義なしの宣言)を理解していると思いますが、それがいつ有用になるのか疑問に思います。

誰かが例を提供できますか?

347
Aslan986

これはグローバル変数があるときに役に立ちます。グローバル変数の 存在 をヘッダー内で宣言するので、ヘッダーを含む各ソースファイルはそれを認識しますが、ソースファイルの1つに1回定義するだけで済みます。

明確にするために、extern int x;を使用すると、intと呼ばれるx型のオブジェクトが存在することがコンパイラに通知されます somewhere 。それが存在する場所を知ることはコンパイラの仕事ではありません、それがそれがそれをどのように使用するかを知っているようにそれはちょうどタイプと名前を知る必要があります。すべてのソースファイルがコンパイルされると、リンカはxのすべての参照を、コンパイルされたいずれかのソースファイルで見つかった1つの定義に解決します。これが機能するためには、x変数の定義に「外部リンケージ」と呼ばれるものが必要です。これは基本的に、関数の外側(通常は「ファイルスコープ」と呼ばれるもの)でstaticキーワードなしで宣言する必要があることを意味します。 。

ヘッダ:

#ifndef HEADER_H
#define HEADER_H

// any source file that includes this will be able to use "global_x"
extern int global_x;

void print_global_x();

#endif

ソース1:

#include "header.h"

// it needs to be defined somewhere
int global_x;

int main()
{
    //set global_x here:
    global_x = 5;

    print_global_x();
}

ソース2:

#include <iostream>
#include "header.h"

void print_global_x()
{
    //print global_x here:
    std::cout << global_x << std::endl;
}
447
dreamlax

いくつかのモジュール間で変数を共有するときに役立ちます。 1つのモジュールでそれを定義し、他のモジュールではexternを使用します。

例えば:

file1.cpp内:

int global_int = 1;

file2.cpp内:

extern int global_int;
//in some function
cout << "global_int = " << global_int;
134
MByD

リンケージ についてのすべてです。

前の回答はexternについて良い説明を提供しました。

しかし重要な点を付け加えたいと思います。

externについては C++ ではなく _ c _ で尋ねていますが、externがC++でconstと一緒になっているケースについて言及している答えがないのはなぜですか。

C++では、const変数はデフォルトで内部リンケージを持ちます(Cとは異なります)。

そのため、このシナリオでは リンクエラー :が発生します。

ソース1:

const int global = 255; //wrong way to make a definition of global const variable in C++

情報源2:

extern const int global; //declaration

このようにする必要があります。

ソース1:

extern const int global = 255; //a definition of global const variable in C++

情報源2:

extern const int global; //declaration
51
Nik

これはグローバル変数を使いたいときに便利です。あるソースファイルでグローバル変数を定義し、それらをヘッダーファイルでexternとして宣言すると、そのヘッダーファイルを含むすべてのファイルが同じグローバル変数を参照できるようになります。

12
Marlon

グローバル変数がある場合、それらが定義されていない任意の翻訳単位でexternを宣言する必要があります。そうしないと、複数の定義が得られます。グローバルは一般に良くないので、もちろんこれは避けるべきです。

Cで書いていて、C++ユーザがあなたのライブラリを使えるようにしたいときは、自分のものをextern "C" {}ブロックで宣言します。 Cは吸うので、これも必要ないはずです。

最後に、どこかでテンプレートのインスタンス化を宣言しているので、新しいインスタンスを作成するのではなくリンクしたいと考えています。あなたはそれらのexternも宣言します。これは時折使用します...多分...私は持っていません。

C++で「extern」を必要とした回数は、片方だけで数えることができると思います。

0
Crazy Eddie