1

Scott Meyer の効果的な C++ の項目 4 を読んでいます。ここで、静的な非ローカル オブジェクトが異なる翻訳単位で使用されている例を示しています。彼は、ある翻訳単位で使用されるオブジェクトが、使用前に他の翻訳単位で初期化されているかどうかを認識できないという問題を強調しています。誰かがコピーを持っている場合に備えて、第 3 版の 30 ページです。

例は次のとおりです。

1 つのファイルがライブラリを表します。

class FileSystem{
    public:
        std::size_t numDisks() const;
    ....
};

extern FileSystem tfs;

そしてクライアントファイルで:

class Directory {
    public:
        Directory(some_params);
    ....
};

Directory::Directory(some_params)
{
    ...
    std::size_t disks = tfs.numDisks();
    ...
}

したがって、私の2つの質問は次のとおりです。

1) クライアント コードで を使用する必要がある場合はtfs、ある種の include ステートメントがあります。したがって、このコードはすべて 1 つの翻訳単位に含まれているのでしょうか? 別の翻訳単位にあるコードを参照する方法がわかりません。確かに、プログラムは常に 1 つの翻訳単位ですか?

2) クライアント コードに FileSystem.h が含まれている場合、クライアント コードがextern FileSystem tfs;tfs を呼び出すにはこの行で十分でしょうか (初期化で実行時の問題が発生する可能性があります。コンパイル時のスコープについて話しているだけです)。

Q1に編集

この本には、これら 2 つのコードは別々の翻訳単位にあると書かれています。tfs別々の翻訳単位にあることを知って、クライアント コードは変数 をどのように使用できますか??

4

3 に答える 3

0

標準 C++03 の例を次に示します (ヘッダーa.hb.hヘッダーを追加しました)。

[basic.start.init]/3

// a.h
struct A { A(); Use(){} };

// b.h
struct B { Use(){} };

// – File 1 –
#include "a.h"
#include "b.h"
B b;
A::A(){
    b.Use();
}

// – File 2 –
#include "a.h"
A a;

// – File 3 –
#include "a.h"
#include "b.h"
extern A a;
extern B b;
int main() {
    a.Use();
    b.Use();
}

a または b が main に入る前に初期化されるかどうか、または a が main で最初に使用されるまで初期化が遅延されるかどうかは実装定義です。特に、main に入る前に a が初期化された場合、a の初期化によって使用される前、つまり A::A が呼び出される前に b が初期化されることは保証されません。ただし、a が main の最初のステートメントの後のある時点で初期化される場合、b は A::A で使用される前に初期化されます。

于 2013-05-05T23:42:22.933 に答える