C++11標準ライブラリのstd::shared_ptrでは、ヌルポインタを所有することが可能となっている。
デフォルトコンストラクトされたshared_ptrオブジェクトは空(empty)となる。一方、明示的にnullptrを与えてコンストラクトしたshared_ptrオブジェクトは “ヌルポインタを所有(own)する” *1。この場合はshared_ptrオブジェクト破棄時にカスタムデリータが呼ばれる。
#include <memory> #include <iostream> int main() { auto custom_deleter = [](void* p){ assert(p == nullptr); std::cout << "deleter called" << std::endl; }; std::shared_ptr<void> sp(nullptr, custom_deleter); } // 標準出力に"deleter called"が出力される
N3337 20.7.2.2/p1, 20.7.2.2.1/p1-2,9-10, 20.7.2.2.2/p1より部分引用。
(snip) A
shared_ptrobject is empty if it does not own a pointer.
constexpr shared_ptr() noexcept;1 Effects: Constructs an empty
shared_ptrobject.
2 Postconditions:use_count() == 0 && get() == 0.template <class Y, class D> shared_ptr(Y* p, D d); template <class D> shared_ptr(nullptr_t p, D d);9 Effects: Constructs a
shared_ptrobject that owns the objectpand the deleterd. (snip)
10 Postconditions:use_count() == 1 && get() == p.
~shared_ptr();1 Effects:
- If
*thisis empty or shares ownership with anothershared_ptrinstance (use_count() > 1), there are no side effects.- Otherwise, if
*thisowns an objectpand a deleterd,d(p)is called.- Otherwise,
*thisowns a pointerp, anddelete pis called.
追記:"empty" の定義が曖昧?
[twitter:@k_satoda]さんからの指摘を受けて。
N3337 20.7.2.2/p1は "A shared_ptr object is empty if it does not own an object a pointer." とすべきかも。
関連URL
*1:ヌルポインタ定数として NULL や 0 を指定した場合も同様の動作となる。