MGL::UniquePtr#

注意

このクラスは現在試験的に実装されています。今後大きな変更が加えられる可能性がある点にご注意ください。

概要#

MGL::UniquePtrは、MGLのアロケータを利用したユニークポインタクラスです。標準ライブラリにおけるstd::unique_ptrと同様にポインタの所有権を単独で占有し、解放処理を自動化します。

MGL::UniquePtrはよりMGLと親和性の高いユニークポインタクラスとして実装されていますが、既存のstd::unique_ptrの完全な代替を目的としたものではありません。状況に応じて、適宜MGL::STL::unique_ptrと使い分けてください。

std::unique_ptrと比較した場合、次のような特徴があります。

内部でMGLのアロケータを用いて構築したオブジェクトのみを扱い、外部からのポインタは受け付けない

std::unique_ptrは外部で構築されたオブジェクトを渡す事が可能ですが、同時に適切なデリータを渡さないと標準のアロケータでデリートしてしまいます。これは独自のアロケータを使用する場合において、しばしばアロケータとデリータの食い違いが生じ、致命的な不具合の要因となり得る問題でした。

MGL::UniquePtrは外部からのポインタは受け付けず、内部でMGLのアロケータを用いて構築したオブジェクトのみを扱います。このため、アロケータとデリータが食い違うことはありません。

なお、MGLのアロケータに独自のアロケータを設定することは可能です。

内部で構築したオブジェクトの所有権は放棄できない

std::unique_ptr::release()に相当する機能はありません。この関数は管理しているポインタを破棄せずに管理を放棄し、その後の管理を外部に委ねるための機能です。(注意:確保したメモリを解放する機能ではありません

MGL::UniquePtrは他のユニークポインタ(またはstd::shared_ptr)にムーブすることは可能ですが、それを除けば構築したオブジェクトを破棄するのは常に自身に限られます。

配列は扱えない

std::unique_ptrは配列の生成が可能ですが、あくまでポインタの代替であるため、配列サイズの管理と範囲外アクセスの防止は利用者に委ねられています。

MGLでは配列をより安全に扱うためのMGL::ArrayおよびMGL::Array2Dがあるため、MGL::UniquePtrでは単一オブジェクトの扱いに特化した作りになっています。どうしても生の配列をユニークポインタで扱う必要がある場合はMGL::STL::unique_ptrを利用してください。

宣言#

namespace MGL
{
    template <class T>
    class UniquePtr;
}

テンプレート引数#

class T

扱うポインタの型

利用例#

次のようなクラスFooと、それを継承したBarがあると仮定する。

class Foo
{
public:
    void Function()
    {
        ...
    }

    ...
};

class Bar : public Foo
{
public:
    void BarOnlyFunction()
    {
        ...
    }

    ...
}
クラスFooを生成
// Fooを指す空のユニークポインタを宣言
MGL::UniquePtr<Foo> foo;

// Foo型のオブジェクトを生成。引数はコンストラクタに渡される。
// MGL::UniquePtr<Foo>::Make() とすることで生成済みのユニークポインタを取得することも可能。
foo.New();

// アロー演算子を用いることで通常のポインタのように取り扱える。
foo->Function();

// 破棄は自動で行われるが、何らかの理由で手動で行うことも可能。
// (デストラクタの呼び出しタイミングを細かく制御したい場合など)
foo.Delete();
詳細
生成したポインタはコピー不可、ムーブは可能
// クラスFooを生成し、ユニークポインタで管理。
auto foo = MGL::UniquePtr<Foo>::Make();

// ❌ユニークポインタなのでコピーは不可。
auto foo2 = foo;    // コンパイルエラー!!

// ✅ムーブは可能。
auto foo3 = std::move(foo); // fooの管理するポインタはfoo3へと移動する。
                            // もしfoo3が生成済みだった場合は先に破棄される。
詳細
継承クラスの扱い
// Foo型のユニークポインタを、Fooを継承したBar型で構築。
MGL::UniquePtr<Foo> foo1;
foo1.New<Bar>();

// Bar型としてアクセスする期間が欲しい場合、InitNew()またはInitMake()を用いる。
MGL::UniquePtr<Foo> foo2;
foo2.InitNew<Bar>([](auto &bar)
{
    bar.BarOnlyFunction();
});
詳細
シェアードポインタへ移行
// クラスFooを生成し、ユニークポインタで管理。
auto foo = MGL::UniquePtr<Foo>::Make();

// fooをstd::shared_ptr<foo>へと移行。
auto sharedFoo = foo.MoveSharedPtr();
詳細

メンバ情報#

種類

名前

内容

バージョン

関数

コンストラクタ

1.1.15+

関数

New

オブジェクトの生成

1.1.15+

関数

InitNew

オブジェクトを初期化関数付きで生成

1.1.15+

関数

Delete

オブジェクトの破棄

1.1.15+

関数

Get

ポインタの取得

1.1.15+

関数

IsNull

ポインタのNullチェック

1.1.15+

関数

Make

ユニークポインタの生成ヘルパー関数

1.1.15+

関数

InitMake

初期化関数付きのユニークポインタの生成ヘルパー関数

1.1.15+

関数

MoveSharedPtr

シェアードポインタへ移行

1.1.15+

オペレータ

operator=

演算子によるムーブ

1.1.15+

オペレータ

operator->

演算子によるメンバアクセス

1.1.15+

オペレータ

operator*

演算子による間接参照

1.1.15+

オペレータ

operator!

演算子によるNullチェック

1.1.15+

オペレータ

operator bool

bool型へのキャストによる有効性のチェック

1.1.15+


コンストラクタ#

宣言#

namespace MGL
{
    template <class T>
    class UniquePtr
    {
    public:
        // (1) 空のユニークポインタを生成
        constexpr UniquePtr() noexcept;

        // (2) ムーブコンストラクタ
        UniquePtr(UniquePtr &&rhs) noexcept;

        // (3) コピーコンストラクタの削除
        UniquePtr(UniquePtr &) = delete;
    };
}

引数#

(1) 空のユニークポインタを生成

引数なし

(2) ムーブコンストラクタ
UniquePtr &&rhs

移動元のユニークポインタ

説明#

UniquePtrクラスにおけるコンストラクタは、空のユニークポインタの生成とムーブのために定義されています。

(1)は引数なしでコンストラクタを呼び出し、空のユニークポインタを生成します。この方法で生成されたクラスに対し、NewまたはInitNewを呼び出すことで有効なポインタを生成できます。

空のユニークポインタを経由せずに有効なポインタを生成する方法として、MakeまたはInitMakeも利用可能です。

注釈

標準ライブラリのstd::unique_ptrとは異なり、本クラスではクラス外で生成したポインタを管理することはできません。このため、コンストラクタに生成済みのポインタを渡して初期化することはできません。

(2)と(3)はムーブのための定義です。このクラスはコピーが禁止されており、ムーブでのみ他のポインタへと移動可能となっています。

ムーブについてはoperator=も併せて参照してください。

利用例#

// int型の空のユニークポインタを生成
MGL::UniquePtr<int> ptr;

// 初期値3でint型のオブジェクトを生成
ptr.New(3);

// ptrが管理しているポインタをptr2にムーブ。
// これによってptrが管理しているポインタはptr2へ移り、移動元のptrの内容はnullptrになる。
MGL::UniquePtr<int> ptr2(std::move(ptr));

// コピーは禁止されているため、次のような記述は不可能。
MGL::UniquePtr<int> ptr3(ptr2);         // コンパイルエラー!!

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


New#

オブジェクトの生成

宣言#

namespace MGL
{
    template <class T>
    class UniquePtr
    {
    public:
        template <class U = T, class... Args>
        UniquePtr &New(Args &&...args) noexcept;
    };
}

テンプレート引数#

class U

生成するポインタの型。省略時はクラスに設定した型。

class... Args

U型のコンストラクタに渡す可変長引数

要件#

UTと同じか、Tを継承したクラスである必要があります。

Argsはその引数リストでU型のコンストラクタを呼び出せる必要があります。

引数#

Args &&... args

U型のコンストラクタに渡す引数

戻り値#

UniquePtr &

生成したユニークポインタの参照

説明#

指定された型のオブジェクトを構築し、このクラスに関連付けます。

オブジェクトはテンプレート引数で指定したU型として構築され、それをクラスに指定したT型のポインタとして管理します。U型はT型と同じか継承関係にある型のみが指定可能です。U型の指定を省略した場合はT型として扱われます。

引数argsU型のコンストラクタにそのまま渡されます。

既に構築済みのオブジェクトを保持している場合、先にそのオブジェクトの破棄が行われます。

U型がT型の派生クラスである場合、この関数ではダウンキャスト以外の方法でU型としてアクセス可能な期間がありません。もし初期化などでU型として扱いたい場合はInitNewを使用してください。

利用例#

int型のユニークポインタを生成する例
MGL::UniquePtr<int> ptr;

ptr.New(3);

MGL_TRACE("*ptr = %d", *ptr);
実行結果
*ptr = 3
Foo型を継承したBar型を、Foo型のユニークポインタとして生成する例
// 基底となるFoo型
class Foo
{
public:
    virtual ~Foo(){}

    virtual void Print()
    {
        MGL_TRACE("Call Foo");
    }
};

// Foo型を継承した派生クラスのBar型
class Bar : public Foo
{
public:
    Bar(int value)
        : _value(value)
    {
    }

    void Print() override
    {
        MGL_TRACE("Call Bar: %d", _value);
    }

private:
    int _value;
};
// Foo型のユニークポインタとして宣言
MGL::UniquePtr<Foo> foo;

// Bar型としてオブジェクトを構築。
// 引数の 3 はBarのコンストラクタへと渡される。
foo.New<Bar>(3);

// Foo型が持つvirtual関数Print()を呼び出し。
// Bar型で構築したポインタであるため、Bar::Print()が呼び出される。
foo->Print();
実行結果
Call Bar: 3

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


InitNew#

オブジェクトを初期化関数付きで生成

宣言#

namespace MGL
{
    template <class T>
    class UniquePtr
    {
    public:
        template <class U = T, class Initializer, class... Args>
        UniquePtr &InitNew(Initializer initializer, Args &&...args) noexcept;
    };
}

テンプレート引数#

class U

生成するポインタの型。省略時はクラスに設定した型。

class Initializer

初期化に使用する関数オブジェクトの型

class... Args

U型のコンストラクタに渡す可変長引数

要件#

UTと同じか、Tを継承したクラスである必要があります。

InitializerU型の参照のみを受ける関数オブジェクトである必要があります。

Argsはその引数リストでU型のコンストラクタを呼び出せる必要があります。

引数#

Initializer initializer

初期化処理の関数オブジェクト

Args &&...args

U型のコンストラクタに渡す引数

戻り値#

UniquePtr &

生成したユニークポインタの参照

説明#

指定された型のオブジェクトを構築し、初期化処理を実行した後にこのクラスに関連付けます。

オブジェクトはテンプレート引数で指定したU型として構築され、それをクラスに指定したT型のポインタとして管理します。U型はT型と同じか継承関係にある型のみが指定可能です。U型の指定を省略した場合はT型として扱われます。

引数initializerには構築したU型のオブジェクトを初期化するための関数オブジェクトを指定します。initializerの引数には構築後のU型のオブジェクトの参照が渡されます。

initializerの戻り値はvoid型、またはbool型が指定可能です。bool型かつfalseを返した場合は構築失敗とみなし、構築したU型のオブジェクトを破棄して自身はNULLとなります。

引数argsU型のコンストラクタにそのまま渡されます。

既に構築済みのオブジェクトを保持している場合、先にそのオブジェクトの破棄が行われます。

注釈

この関数はU型が派生オブジェクト、かつコンストラクタ以外での初期化処理を要する場合を想定して実装されています。コンストラクタ呼び出しのみで初期化が完結する場合はNewを使用してください。

利用例#

Foo型を継承し、初期化関数を持ったBar型を、Foo型のユニークポインタとして生成する例
// 基底となるFoo型
class Foo
{
public:
    virtual ~Foo(){}

    virtual void Print()
    {
        MGL_TRACE("Call Foo");
    }
};

// Foo型を継承した派生クラスのBar型
class Bar : public Foo
{
public:
    void Initialize(int value)
    {
        _value = value;
    }

    void Print() override
    {
        MGL_TRACE("Call Bar: %d", _value);
    }

private:
    int _value{0};
};
// Foo型のユニークポインタとして宣言
MGL::UniquePtr<Foo> foo;

// Bar型としてオブジェクトを構築し、初期化関数 Initialize() を呼び出す。
foo.InitNew<Bar>([](auto &bar)
{
    bar.Initialize(3);
});

// Foo型が持つvirtual関数Print()を呼び出し。
// Bar型で構築したポインタであるため、Bar::Print()が呼び出される。
foo->Print();
実行結果
Call Bar: 3

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


Delete#

オブジェクトの破棄

宣言#

namespace MGL
{
    template <class T>
    class UniquePtr
    {
    public:
        void Delete() noexcept;
    };
}

説明#

有効なオブジェクトを保持している場合に、その内容を破棄します。

構築したオブジェクトはMGL::UniquePtrクラスの寿命に同期して破棄されるため、この関数を必ず呼び出す必要はありません。オブジェクトの寿命を厳格に管理したい場合に使用してください。

利用例#

// int型のユニークポインタを宣言
MGL::UniquePtr<int> ptr;

// int型のオブジェクトを初期値 3 で生成
ptr.New(3);

// 生成したオブジェクトを破棄(呼び出さなくてもOK)
ptr.Delete();

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


Get#

ポインタの取得

宣言#

namespace MGL
{
    template <class T>
    class UniquePtr
    {
    public:
        [[nodiscard]] constexpr T *Get() const noexcept;
    };
}

戻り値#

T *

構築したオブジェクトのT型のポインタ。未構築の場合はnullptr

説明#

構築済みのオブジェクトのポインタを取得します。オブジェクトが構築されていない場合、この関数はnullptrを返します。

この関数が返す値はoperator->と等価になります。

利用例#

// int型のユニークポインタを宣言
MGL::UniquePtr<int> ptr;

// Get()でptrのポインタを取得
if (auto *p = ptr.Get(); p != nullptr)
{
    // まだ構築されていないため、ここには到達しない。
}

// ptrのオブジェクトを構築
ptr.New(3);

// 再びGet()でptrのポインタを取得
if (auto *p = ptr.Get(); p != nullptr)
{
    // 構築済みであるため、有効なポインタ p にアクセス可能。
}

バージョン情報#

MGL 1.1.15
  • 初回リリース


IsNull#

ポインタのNullチェック

宣言#

namespace MGL
{
    template <class T>
    class UniquePtr
    {
    public:
        [[nodiscard]] constexpr bool IsNull() const noexcept;
    };
}

戻り値#

bool

保持しているオブジェクトが構築されていない場合にtrue、構築済みの場合はfalse

説明#

オブジェクトが未構築な場合にtrueを返します。

この関数がtrueを返す状態においては、operator->およびoperator*の呼び出しは未定義動作となります。

この関数の返す値はoperator!と等価であり、operator boolを反転させた値と等価です。

利用例#

// int型のユニークポインタを宣言
MGL::UniquePtr<int> ptr;

// ptrが構築されているかをチェック
if (ptr.IsNull())       // 単に if (!ptr) でもOK
{
    // まだ構築されていないため、ここに到達する。
}

// ptrのオブジェクトを構築
ptr.New(3);

// 再びptrが構築されているかをチェック
if (ptr.IsNull())
{
    // 構築済みであるため、ここには到達しない。
}

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


Make#

ユニークポインタの生成ヘルパー関数

宣言#

namespace MGL
{
    template <class T>
    class UniquePtr
    {
    public:
        template <class U = T, class... Args>
        [[nodiscard]] static UniquePtr Make(Args &&...args) noexcept;
    };
}

テンプレート引数#

class U

生成するポインタの型。省略時はクラスに設定した型。

class... Args

U型のコンストラクタに渡す可変長引数

要件#

UTと同じか、Tを継承したクラスである必要があります。

Argsはその引数リストでU型のコンストラクタを呼び出せる必要があります。

引数#

Args &&... args

U型のコンストラクタに渡す引数

戻り値#

UniquePtr

生成したユニークポインタ

説明#

オブジェクト構築済みのユニークポインタを生成するためのヘルパー関数です。この関数はNewとは異なり静的に呼び出し可能で、構築したユニークポインタを戻り値として返します。

オブジェクトはテンプレート引数で指定したU型として構築され、それをクラスに指定したT型のポインタとして管理します。U型はT型と同じか継承関係にある型のみが指定可能です。U型の指定を省略した場合はT型として扱われます。

引数argsU型のコンストラクタにそのまま渡されます。

U型がT型の派生クラスである場合、この関数ではダウンキャスト以外の方法でU型としてアクセス可能な期間がありません。もし初期化などでU型として扱いたい場合はInitMakeを使用してください。

利用例#

int型のユニークポインタを生成する例
auto ptr = MGL::UniquePtr<int>::Make(3);

MGL_TRACE("*ptr = %d", *ptr);
実行結果
*ptr = 3
Foo型を継承したBar型を、Foo型のユニークポインタとして生成する例
// 基底となるFoo型
class Foo
{
public:
    virtual ~Foo(){}

    virtual void Print()
    {
        MGL_TRACE("Call Foo");
    }
};

// Foo型を継承した派生クラスのBar型
class Bar : public Foo
{
public:
    Bar(int value)
        : _value(value)
    {
    }

    void Print() override
    {
        MGL_TRACE("Call Bar: %d", _value);
    }

private:
    int _value;
};
// Foo型のユニークポインタをBar型で構築
auto foo = MGL::UniquePtr<Foo>::Make<Bar>(3);

// Foo型が持つvirtual関数Print()を呼び出し。
// Bar型で構築したポインタであるため、Bar::Print()が呼び出される。
foo->Print();
実行結果
Call Bar: 3

ヒント

テンプレート引数の指定が多く読みにくいと感じた場合、次のようにエイリアス宣言を用いることで読みやすくなる場合があります。

int型の場合
using IntPtr = MGL::UniquePtr<int>;

auto iptr = IntPtr::Make(3);
Foo型の場合
using FooPtr = MGL::UniquePtr<Foo>;

auto foo = FooPtr::Make<Bar>(3);

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


InitMake#

初期化関数付きのユニークポインタの生成ヘルパー関数

宣言#

namespace MGL
{
    template <class T>
    class UniquePtr
    {
    public:
        template <class U = T, class Initializer, class... Args>
        [[nodiscard]] static UniquePtr InitMake(Initializer initializer, Args &&...args) noexcept;
    };
}

テンプレート引数#

class U

生成するポインタの型。省略時はクラスに設定した型。

class Initializer

初期化に使用する関数オブジェクトの型

class... Args

U型のコンストラクタに渡す可変長引数

要件#

UTと同じか、Tを継承したクラスである必要があります。

InitializerU型の参照のみを受ける関数オブジェクトである必要があります。

Argsはその引数リストでU型のコンストラクタを呼び出せる必要があります。

引数#

Initializer initializer

初期化処理の関数オブジェクト

Args &&...args

U型のコンストラクタに渡す引数

戻り値#

UniquePtr

生成したユニークポインタ

説明#

オブジェクト構築済みのユニークポインタを生成するための、初期化関数を指定可能なヘルパー関数です。この関数はInitNewとは異なり静的に呼び出し可能で、構築したユニークポインタを戻り値として返します。

オブジェクトはテンプレート引数で指定したU型として構築され、それをクラスに指定したT型のポインタとして管理します。U型はT型と同じか継承関係にある型のみが指定可能です。U型の指定を省略した場合はT型として扱われます。

引数initializerには構築したU型のオブジェクトを初期化するための関数オブジェクトを指定します。initializerの引数には構築後のU型のオブジェクトの参照が渡されます。

initializerの戻り値はvoid型、またはbool型が指定可能です。bool型かつfalseを返した場合は構築失敗とみなし、構築したU型のオブジェクトを破棄して自身はNULLとなります。

引数argsU型のコンストラクタにそのまま渡されます。

注釈

この関数はU型が派生オブジェクト、かつコンストラクタ以外での初期化処理を要する場合を想定して実装されています。コンストラクタ呼び出しのみで初期化が完結する場合はMakeを使用してください。

利用例#

Foo型を継承し、初期化関数を持ったBar型を、Foo型のユニークポインタとして生成する例
// 基底となるFoo型
class Foo
{
public:
    virtual ~Foo(){}

    virtual void Print()
    {
        MGL_TRACE("Call Foo");
    }
};

// Foo型を継承した派生クラスのBar型
class Bar : public Foo
{
public:
    void Initialize(int value)
    {
        _value = value;
    }

    void Print() override
    {
        MGL_TRACE("Call Bar: %d", _value);
    }

private:
    int _value{0};
};
// Foo型のユニークポインタをBar型として構築。
// 初期化は引数で指定する初期化関数にて行う。
auto foo = MGL::UniquePtr<Foo>::InitMake<Bar>([](auto &bar)
{
    bar.Initialize(3);
});

// Foo型が持つvirtual関数Print()を呼び出し。
// Bar型で構築したポインタであるため、Bar::Print()が呼び出される。
foo->Print();
実行結果
Call Bar: 3

ヒント

テンプレート引数の指定が多く読みにくいと感じた場合、次のようにエイリアス宣言を用いることで読みやすくなる場合があります。

using FooPtr = MGL::UniquePtr<Foo>;

auto foo = FooPtr::InitMake<Bar>([](auto &bar)
{
    ...
});

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


MoveSharedPtr#

シェアードポインタへ移行

宣言#

namespace MGL
{
    template <class T>
    class UniquePtr
    {
    public:
        std::shared_ptr<T> MoveSharedPtr();
    };
}

戻り値#

std::shared_ptr<T>

移行後のシェアードポインタ

説明#

このクラスが保持しているオブジェクトの管理を、標準ライブラリのstd::shared_ptrへと移行します。移行後、このクラスはNullとなります。

std::shared_ptrの扱い方については標準ライブラリのドキュメントを参照してください。

利用例#

// int型のユニークポインタを宣言
MGL::UniquePtr<int> ptr;

// 初期値3でint型のオブジェクトを構築
ptr.New(3);

// std::shared_ptr<int> 型の sharedPtr に移行。
// この際、元のptrはNULLになる。
auto sharedPtr = ptr.MoveSharedPtr();

バージョン情報#

MGL 1.1.15
  • 初回リリース


operator=#

演算子によるムーブ

宣言#

namespace MGL
{
    template <class T>
    class UniquePtr
    {
    public:
        // (1) 演算子によるムーブ
        UniquePtr &operator=(UniquePtr &&rhs) noexcept;

        // (2) コピーを禁止するための宣言
        UniquePtr &operator=(UniquePtr &) = delete;
    };
}

引数#

UniquePtr &&rhs

ムーブ元のユニークポインタ

戻り値#

UniquePtr &

ムーブ後のユニークポインタ

説明#

=演算子によるムーブ、およびコピーを禁止するための宣言です。

=演算子の右辺が右辺値参照である場合、その内容を左辺値へとムーブします。右辺が右辺値参照ではない場合は禁止されているコピーとなるため、コンパイルエラーとなります。

利用例#

// int型の空のユニークポインタを生成
MGL::UniquePtr<int> ptr;

// 初期値3でint型のオブジェクトを生成
ptr.New(3);

// ptrが管理しているポインタをptr2にムーブ。
// これによってptrが管理しているポインタはptr2へ移り、移動元のptrの内容はnullptrになる。
auto ptr2 = std::move(ptr);

// コピーは禁止されているため、次のような記述は不可能。
auto ptr3 = ptr2;   // コンパイルエラー!!

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


operator->#

演算子によるメンバアクセス

宣言#

namespace MGL
{
    template <class T>
    class UniquePtr
    {
    public:
        [[nodiscard]] constexpr T *operator->() const noexcept;
    };
}

戻り値#

T *

構築したオブジェクトのT型のポインタ。未構築の場合はnullptr

説明#

構築済みのオブジェクトのポインタを返し、通常のポインタ変数と同様にメンバアクセスを可能にするためのオペレータです。

オブジェクトが構築されていない場合はnullptrを返すため、Nullチェックを行わずにアクセスした場合の未定義動作性についても通常のポインタ変数と同等です。

この関数が返す値はGetと等価になります。

利用例#

class Foo
{
public:
    void Print()
    {
        MGL_TRACE("Call Foo");
    }
};
// Foo型のユニークポインタfooを生成
auto foo = MGL::UniquePtr<Foo>::Make();

// fooが有効である場合に->演算子を用いてPrint()を呼び出し。
if (foo)
{
    foo->Print();
}

// fooの有効性をチェックせずに呼び出した場合、fooが構築前であれば未定義動作となる。
foo->Print();

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


operator*#

演算子による間接参照

宣言#

namespace MGL
{
    template <class T>
    class UniquePtr
    {
    public:
        [[nodiscard]] constexpr std::add_lvalue_reference_t<T> operator*() const noexcept;
    };
}

戻り値#

T &

構築したオブジェクトのT型のポインタ。未構築の場合は未定義動作。

説明#

構築済みのオブジェクトの参照を返し、通常のポインタ変数と同様に間接参照を行うためのオペレータです。

オブジェクトが構築されていない場合はnullptrからの間接参照となり未定義動作となる点も、通常のポインタ変数における間接参照と同等です。

利用例#

int型で構築したユニークポインタの内容を間接参照でトレース表示する例
// int型のユニークポインタを初期値3で構築
auto ptr = MGL::UniquePtr<int>::Make(3);

// ptrの内容をトレース表示
if (ptr)
{
    MGL_TRACE("*ptr = %d", *ptr);
}

// 有効性をチェックせずに間接参照を行った場合、ptrが構築前であれば未定義動作となる。
MGL_TRACE("*ptr = %d", *ptr);
実行結果
*ptr = 3
*ptr = 3

バージョン情報#

MGL 1.1.15
  • 初回リリース


operator!#

演算子によるNullチェック

宣言#

namespace MGL
{
    template <class T>
    class UniquePtr
    {
    public:
        [[nodiscard]] constexpr bool operator!() const noexcept;
    };
}

戻り値#

bool

保持しているオブジェクトが構築されていない場合にtrue、構築済みの場合はfalse

説明#

演算子によるNullチェックを行うためのオペレータです。

この関数がtrueを返す状態においては、operator->およびoperator*の呼び出しは未定義動作となります。

この関数の返す値はIsNullと等価であり、operator boolを反転させた値と等価です。

利用例#

// int型のユニークポインタを宣言
MGL::UniquePtr<int> ptr;

// ptrが構築されているかをチェック
if (!ptr)
{
    // まだ構築されていないため、ここに到達する。
}

// ptrのオブジェクトを構築
ptr.New(3);

// 再びptrが構築されているかをチェック
if (!ptr)
{
    // 構築済みであるため、ここには到達しない。
}

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#


operator bool#

bool型へのキャストによる有効性のチェック

宣言#

namespace MGL
{
    template <class T>
    class UniquePtr
    {
    public:
        [[nodiscard]] explicit constexpr operator bool() const noexcept;
    };
}

戻り値#

bool

保持しているオブジェクトが構築済みの場合にtrue、構築されていない場合はfalse

説明#

オブジェクトの有効性をチェックするためのbool型へのキャストを行うオペレータです。オブジェクトが構築済みである場合にtrueを返します。

この関数の返す値はIsNullおよびoperator!を反転させた値と等価です。

利用例#

// int型のユニークポインタを宣言
MGL::UniquePtr<int> ptr;

// ptrが構築されているかをチェック
if (ptr)
{
    // まだ構築されていないため、ここには到達しない。
}

// ptrのオブジェクトを構築
ptr.New(3);

// 再びptrが構築されているかをチェック
if (ptr)
{
    // 構築済みであるため、ここに到達する。
}

バージョン情報#

MGL 1.1.15
  • 初回リリース

関連#