16

いくつかのオブジェクトがあり、各オブジェクトの有効期間中に変更/繰り返されない一意の識別子を生成する必要があります。

基本的に、オブジェクトの一意の ID を取得/生成したいのですが、このように

int id = reinterpret_cast<int>(&obj);

また

int id = (int)&obj;

int はアドレスなどを格納するのに十分な大きさではない可能性があるため、上記のコードは悪い考えであることを理解しています.

オブジェクトから一意の識別子を取得するためのベストプラクティスは何ですか?これは移植可能なソリューションになりますか?

4

6 に答える 6

18

「一意性」の要件に応じて、いくつかのオプションがあります。

  • 1 つのアドレス空間内 (「1 つのプログラム実行内」) で一意であり、オブジェクトがメモリ内の場所にとどまる場合、ポインターは問題ありません。ただし、落とし穴があります。オブジェクトがコンテナー内にある場合、再割り当てのたびにオブジェクトの ID が変更される可能性があり、オブジェクトのコピーを許可すると、関数から返されたオブジェクトが同じアドレスに作成される可能性があります。
  • よりグローバルな一意性が必要な場合、たとえば永続的な通信プログラムまたはデータを扱っている場合は、boost.uuid などの GUID/UUId を使用します
  • いくつかの静的カウンターから一意の整数を作成できますが、落とし穴に注意してください。
    • インクリメントがアトミックであることを確認してください
    • コピーから保護するか、カスタム コピー コンストラクター、代入ステートメントを作成します。

個人的には、すべての落とし穴について考える必要がなく、安心できるので、余裕があるときはいつでも UUID を選択しました。

于 2013-01-29T14:56:09.377 に答える
11

オブジェクトを一意に識別する必要がある場合は、コンストラクターで一意の ID を生成できます。

struct Obj
{ 
   int _id;
   Obj() { static int id = 0; _id = id++; }
};

コピー/割り当てをどのように処理するかを決定する必要があります (同じ ID - 上記は機能します / 異なる ID -ローカル変数staticの代わりにコピー コンストラクターとおそらくクラス メンバーが必要です)。static

于 2013-01-29T14:39:41.773 に答える
5

この問題を調べたところ、かなり早くBoost UUID ライブラリ(普遍的に一意の識別子、http://www.boost.org/doc/libs/1_52_0/libs/uuid/)にたどり着きました。ただし、プロジェクトが成長するにつれて、QtのGUIDライブラリ(グローバルに一意の識別子、https://doc.qt.io/qt-5/quuid.html)に切り替えました。

しかし、私が学んだ教訓は、独自のUUIDクラスの宣言を開始し、実装を非表示にして、後で適切と思われるものに切り替えることができるようにすることでした。

それがお役に立てば幸いです。

于 2013-01-29T14:43:44.547 に答える
0

オブジェクトがクラスの場合は、腸を0にする静的メンバー変数を使用できます。次に、コンストラクターでこの値をクラスインスタンスに格納し、静的変数をインクリメントします。

クラス

Indexed
{
public:
   Indexed() :
       m_myIndex( m_nextIndex++ )
   { }

   int getIndex() const
   { return m_myIndex; }

private:
   const int m_myIndex;
   static int m_nextIndex;
};
于 2013-01-29T14:41:41.317 に答える
0

オブジェクト アドレスを一意の (この実行の) 識別子として直接使用することは、悪い考えではないように見えます。なぜ整数にキャストするのですか? ポインターを==次のように比較するだけです。

MyObject *obj1, *obj2;
...
if (obj1 == obj2) ...

もちろん、ID をデータベースなどに書き込む必要がある場合、これは機能しません。実行間でポインターの同じ値が可能です。また、比較演算子 ( ) をオーバーロードしないでください==

于 2013-01-29T14:44:00.913 に答える
0

分散環境で一意の ID が必要な場合は、boost::uuidを使用します

于 2013-01-29T14:44:56.633 に答える