2

私は C++ で複数のファイルをいじっていますが、次の例はコンパイルされません。

main.cpp

#include <iostream>
#include "const.hpp"

using namespace std;

int main()
{
    extern double var;
    var = 5;
    cout << var << endl;

    return 0;
}

fct.cpp

#include <iostream>
#include "const.hpp"

using namespace std;

void func()
{
    extern double var;
    cout << var << endl;

}

const.hpp

#ifndef CONST_H
#define CONST_H

double var;

#endif

どうやらvarの複数定義があるため、私のプログラムはコンパイルされません。この例に基づいて、ヘッダー ファイルは上記の例のように変数を宣言するために使用されることを意図していないと仮定するのは正しいですか?

代わりに、正しい手順は、.cpp ファイル内のすべての変数を宣言し、ヘッダーを使用して、.cpp ファイルに外部 ( extern ) 変数が含まれていることを各 (関連する) 翻訳単位に伝えることですか?

編集:ヘッダーで定義する必要がある定数変数(const)を扱う場合、上記の私のルールの例外は正しいですか?

4

2 に答える 2

4

double var;は定義です-そのヘッダーを複数のファイルに含めると、1つの定義規則に違反します。グローバルが必要な場合(よく考えてください)、ヘッダーで宣言するextern double var;必要があります-そして定義を単一の実装ファイルに移動します。

于 2013-02-26T14:14:11.207 に答える
3

この例に基づいて、ヘッダー ファイルは上記の例のように変数を宣言するために使用されることを意図していないと仮定するのは正しいですか?

ヘッダー ファイルは変数を宣言することを目的としていますが、ヘッダー ファイルは外部リンケージを持つグローバル変数を定義しており、複数回インポートされています。次に、リンカーは、複数定義されたシンボルについて合理的に文句を言います。

代わりに、正しい手順は、.cpp ファイル内のすべての変数を宣言し、ヘッダーを使用して、.cpp ファイルに外部 (extern) 変数が含まれていることを各 (関連する) 翻訳単位に伝えることですか?

はい。ただし、そのファイルでグローバル変数を宣言するのではなく、それらの定義を提供します。.cpp

const.hpp

    #ifndef CONST_H
    #define CONST_H

    // ...

    extern double var;
//  ^^^^^^

    #endif

globals.cpp(ファイルが1 つだけ.cppである限り、他のファイルでもかまいません)

    // ...

    double var;

また、この場合にインクルード ガードが保護されない理由が気になる場合は、これが役立つ可能性があります。

上記のルールの例外は、ヘッダーで定義する必要がある定数変数 (const) を扱う場合であるというのは正しいですか?

ある意味、そうです。グローバル変数はデフォルトで内部リンケージconstを持つと見なされます。つまり、各翻訳単位はその変数のプライベートコピーを受け取ります。そのため、変数の定義が複数の翻訳単位に含まれている場合でも、リンカーは複数定義されたシンボルについて文句を言いません。

于 2013-02-26T14:18:34.373 に答える