LoginSignup
6
3

More than 1 year has passed since last update.

[小ネタ]C++で簡単なID生成器を作った

Last updated at Posted at 2021-10-08

はじめに

ゲームとか作ってると雑にIDを割り振りたくなる場面があったりしますよね。
(なんかオブジェ生成するたびにIdをインクリメントして設定したりしてました)

ただ、雑にインクリメントするだけだと、使い終わったIdを再利用したりできず、インクリメントしつづけていつかオーバーフローするんじゃないかといった恐怖があったので、

使用しなくなったIDを再利用もできるような、簡単なID生成器を作りました。


追記
コメントいただいたのですが、そもそも64bit整数で管理する分には非現実レベルに長時間動かし続けない限りオーバフローすることはなさそうでした。
ようやくオーバフローした頃には、既に自分も墓の中にいるので大丈夫そうですね!

実装

いたってシンプルです。

IdGenerator.hpp
#include <cstdint>
#include <queue>
#include <limits>
#include <exception>

/// <summary>
/// Id生成器
/// </summary>
class IdGenerator
{
public:
    using value_type = std::int64_t;
public:
    /// <summary>
    /// Idの生成
    /// </summary>
    /// <returns></returns>
    value_type createId()
    {
        if (!m_freeIds.empty()) {
            auto id = m_freeIds.front();
            m_freeIds.pop();
            return id;
        }
        if (m_nextId == std::numeric_limits<value_type>::max()) [[unlikely]] {
            throw std::runtime_error("can't be generated Id by max limit.");

            // Fail Safeでもよい
        }
        return m_nextId++;
    }        

    /// <summary>
    /// Idの開放
    /// </summary>
    /// <param name="id"></param>
    void releaseId(value_type id)
    {
        m_freeIds.push(id);
    }        

    /// <summary>
    /// リセット
    /// </summary>
    void reset()
    {
        m_nextId = 0;

        // queue clear
        std::queue<value_type> empty;
        m_freeIds.swap(empty);
    }        
private:
    value_type m_nextId = 0;
    std::queue<value_type> m_freeIds;
};

基本はインクリメントしていく、使い終わったIDはreleaseIdメソッドに渡すことで
キューにため込んでおき、キューが空じゃない時はそこからポップしてIdを返すようにしています。

⚠️未生成なIdをリリースしたらバグりますが、いちいちvalidationするのもコストなのでその辺はやってないです。

使い方

    IdGenerator idGen;

    // ID生成
    auto id_0 = idGen.createId(); // 0

    // ID生成
    auto id_1 = idGen.createId(); // 1

    // ID 0 使い終わった
    idGen.releaseId(id_0);

    // ID生成 再利用される
    auto new_id_0 = idGen.createId(); // 0

    // ID生成
    auto id_2 = idGen.createId(); // 2

まとめ

今回は小ネタでしたが、簡単に使えるID生成器を紹介しました。
使い終わったIDを再利用してオーバーフローしないように安心感を得ましょう。

6
3
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3