1

そのようなライブラリがあると想像してください:

Library.h

   class DLLEXPORT LibraryClass
    {
    private:
      int _id;
      static int _last_id;
    public:
      LibraryClass();
      bool operator == (const LibraryClass t)
      {return _id == t._id;}
    };

ライブラリ.cpp

#include "Library.h"

int LibraryClass::_last_id = 0;

LibraryClass::LibraryClass()
_id(_last_id)
{
++_last_id;
}

それは正しく動作しますか?Visual Studio で C4835 警告が表示されますが、動作しているようです。他のコンパイラでどのように動作するか知っている人はいますか (Linux gcc と mac gcc に興味があります)。そのようなパターンの別の「有効な」実装はありますか?

4

2 に答える 2

1

あなたの構文は問題なく、コードで問題が発生することはありません。これをコンパイルしている間、UNIX/MAC システムで警告が表示されることはないと思います (Windows 指向の DLL エクスポートを行っているという事実を除いて)。マネージ C++ の影響が見られているだけだと思います。

MSDN から:

'variable' : エクスポートされたデータの初期化子は、マネージ コードがホスト アセンブリで最初に実行されるまで実行されません。

マネージ コンポーネント間でデータにアクセスする場合は、ネイティブ C++ のインポートおよびエクスポート メカニズムを使用しないことをお勧めします。代わりに、マネージド型内でデータ メンバーを宣言し、クライアントで #using を使用してメタデータを参照します。詳細については、#using ディレクティブ (C/C++) を参照してください。

unix でコンパイルすると、静的データ メンバーはプログラムの初期化されたテスト セグメントになります。実行前に指定した値に初期化されることが保証されているため、0 から開始され、呼び出されるまでにコンストラクターで完全に使用できるようになります。

于 2012-05-25T15:07:11.343 に答える
1

ドキュメントによると、初期化フェーズ ( の前) で値を使用しようとした場合にのみ問題が発生するようですmainどうやら管理モードに関連する問題。

C++ 標準はこれに関して非常に明確です。動的初期化の前_last_idに最初に静的に初期化され0ます。つまり、適合するコンパイラは期待どおりに動作するコードを生成します。

したがって、gcc と clang (OS に関係なく) で動作します。

Visual Studio の場合、問題が体系的に発生するのか、それともいくつかのフラグを使用して管理モードが必要な場合にのみ発生するのかはわかりません (十分に精通していません) 。

于 2012-05-25T15:07:15.963 に答える