0

プログラム#1

// file.h
class File
{
public:
    static const int var = 9;
};

-

// main.cpp
#include <iostream>
#include "file.h"
using namespace std;

int main() {
    File f;
    cout << f.var;
    return 0;
}

プログラム#2

// file.h
int GlobalVar ;
class File
{
public:
    static const int var = 9;
};

-

// main.cpp
extern int GlobalVar;

#include <iostream>
#include "file.h"
using namespace std;

int main() {
    cout << GlobalVar;
    return 0 ;
}

プログラム#1は正常に実行されていますが、プログラム#2でリンカーエラーが発生します。

error LNK2005: "int GlobalVar" (?x@@3HA) already defined in file.obj

ヘッダーファイルがコンパイルされないことは知っています。次に、上記の場合、コンパイラは変数varの定義を知っていますが、GlobalVar?の定義を見つけることができません。この2つのプログラムの違いは何ですか?

4

2 に答える 2

7

使用する場合

#include "some_header.h"

また

#include <some_header.h>

これらのincludeディレクティブは、の内容を持つプリプロセッサによって直接*置き換えられsome_header.hます。

したがって、cppファイルをコンパイルすると、実際にはの内容が含まれますsome_header.h。これがこのコードのコンパイル方法です。

*-ガードが含まれている場合、他のヘッダーにすでに含まれているコンテンツはスキップされます


編集:あなたの編集に関して-約extern:これはそれを行う正しい方法ではありません。

extern int GlobalVar ;

ヘッダーに配置する必要があり、

int Globalvar ;

cppファイルにあるはずです。externそれがどのように機能し、何をするのかを理解するためにもう少し読む必要があります(ヒント:1つの場所で定義され、複数のcppファイルで到達可能な変数を1つだけにしたい場合、どのように行いますか?たくさんありますSOでも、このケースについての質問)。

于 2012-12-21T13:54:07.513 に答える
0

static const データ メンバーには、インライン関数 (クラス宣言内またはインラインとしてマークされたヘッダー ファイルで定義された関数) の許可と同様の一定の許可があります。プリミティブ型 (整数など) の static const データ メンバーの場合、ヘッダー ファイルでそれらを定義することが許可されます。たとえそれが技術的に One Definition Rule (ODR) 違反につながるとしても、そのようなプリミティブ型の場合、すべてリンカによって見られるこれらのデータ メンバのインスタンスは、同じヘッダー ファイルからのものであり、それらはすべて等しいと想定しても安全です。また、それらは一定であるため、多数のコピーを作成しても問題ありません (または完全に最適化しても問題ありません)。また、それらはプリミティブ型 (自明なコンストラクターを使用) であるため、(複数の翻訳単位での) 静的データ メンバーの複数の構築による副作用の問題はありませんが、非プリミティブの場合、次の保証が必要です。構築は、静的初期化中に 1 回だけ行われます。したがって、明らかに、この例外的な規則は、非 const および/または非プリミティブ (クラス型) の静的データ メンバーには適用されません。この場合、それらは 1 つの翻訳単位 (1 つのコンパイル済み cpp ファイル) でのみ定義する必要があります。 .

于 2012-12-23T05:12:15.893 に答える