3

Bjarne Stroustrup 著 The C++ Programming Language の中で、著者は次のように述べています。

ライブラリを設計するとき、初期化とクリーンアップのみを目的として、コンストラクタとデストラクタを使用して型を作成することが必要な場合や、単純に便利な場合があります。このような型は、コンストラクタとデストラクタが呼び出されるように静的オブジェクトを割り当てるために、一度だけ使用されます。例えば:

 class  Zlib_init
{
    Zlib_init() ; //get Zlib ready for use
   ~Zlib_init()  ; //clean up after Zlib
};
Class Zlib
{
   static  Zlib_init   x;
   /  /...
};

残念ながら、そのようなオブジェクトが最初に使用される前に初期化され、個別にコンパイルされたユニットからなるプログラムで最後に使用された後に破棄されることは保証されていません。

なぜ作成者はコンストラクタとデストラクタをプライベート メンバーとして保持するのですか? また、個別にコンパイルされたユニットで構成されるプログラムでこの方法を使用すると、なぜこの方法が機能しないのでしょうか? コンストラクタとデストラクタxを呼び出すためのメンバーの定義が必要ではないでしょうか? では、この方法の用途は何ですか?本のセクション 10.4.9 にあります。Zlib_init()~Zlib_init()

4

2 に答える 2

8

なぜ作成者はコンストラクタとデストラクタをプライベート メンバーとして保持するのですか?

コンストラクタとデストラクタprivateはタイプミスのようです。
クラスstaticメンバーを使用するには、クラス メンバーを定義する必要あります。静的メンバーを定義するには、コンストラクターにアクセスできる必要があります。そうでない場合、リンカーは未定義の参照について文句を言います。 x

オンラインサンプル:

class  Zlib_init 
{    
   Zlib_init() ; //get Zlib ready for use  
  ~Zlib_init()  ; //clean up after Zlib 
   public:
     int j;
};
class Zlib 
{  
   public:  
   static  Zlib_init   x;    
}; 

Zlib_init Zlib::x;

int main()
{
    Zlib::x.j = 10;

    return 0;
}

出力:

prog.cpp:3: error: ‘Zlib_init::Zlib_init()’ is private     
prog.cpp:14: error: within this context      
prog.cpp: In static member function ‘static void Zlib::__static_initialization_and_destruction_0(int, int)’:     
prog.cpp:4: error: ‘Zlib_init::~Zlib_init()’ is private     
prog.cpp:14: error: within this context     

個別にコンパイルされたユニットで構成されるプログラムでこの方法を使用すると、なぜこの方法が機能しないのでしょうか?

コンストラクタとデストラクタpublicを作成するかZlib、クラスのフレンドをZlib_init作成して上記のタイプミスを修正しても、コードは別の問題に直面します。
この問題は、一般に C++ のStatic Initialization Fiascoとして知られています。

よく読んだ:

[10.14] 「静的初期化順序の大失敗」とは?
[10.17] 静的データ メンバーの「静的初期化順序の大失敗」を防ぐにはどうすればよいですか?

于 2012-10-05T06:36:57.767 に答える
1

なぜ作成者はコンストラクタとデストラクタをプライベート メンバーとして保持するのですか?

推測にすぎませんが、著者は自分の考えを伝えるために必要最小限の宣言を削除したと思います。a のstruct代わりに aclassを使用しても同様に機能しますが、彼の本の他の場所では、著者はそのような場合に省略記号 (...) を使用しています。よくわかりません。

また、個別にコンパイルされたユニットで構成されるプログラムでこの方法を使用すると、なぜこの方法が機能しないのでしょうか?

静的オブジェクトのコンストラクターは の前に実行されるため、 from と呼ばれるものでmainのみ使用すると、すべてがうまく機能します。他のコンパイル単位の他の静的オブジェクトがそのコンストラクターで使用しようとすると、問題が発生します。これら 2 つのコンストラクターが実行される順序についての保証はないため、初期化されていないクラスを使用しようとするコードが発生する可能性があります。ZlibmainZlibZlib

于 2012-10-05T07:04:35.630 に答える