- cpp14[meta cpp]
C++03ではクラス用のdelete
演算子として、サイズをとるバージョンをオーバーロードできた。C++14では、それに対応するグローバルのdelete
演算子を定義できるようにする。
C++14では、オーバーロード可能なグローバルのnew
演算子、delete
演算子として、以下を許可する:
operator new(std::size_t)
operator new(std::size_t, const std::nothrow_t&)
operator new[](std::size_t)
operator new[](std::size_t, const std::nothrow_t&)
operator delete(void*)
operator delete(void*, const std::nothrow_t&)
operator delete[](void*)
operator delete[](void*, const std::nothrow_t&)
operator delete(void*, std::size_t) // C++14から追加
operator delete(void*, std::size_t, const std::nothrow_t&) // C++14から追加(ただし、備考を参照)
operator delete[](void*, std::size_t) // C++14から追加
operator delete[](void*, std::size_t, const std::nothrow_t&) // C++14から追加(ただし、備考を参照)
- std::nothrow_t[link /reference/new/nothrow_t.md]
追加分の詳細なインタフェースは、以下のようになっている:
void operator delete(void* ptr, std::size_t size) noexcept;
void operator delete(void* ptr, std::size_t size,
const std::nothrow_t&) noexcept; // ただし、備考を参照
void operator delete[](void* ptr, std::size_t size) noexcept;
void operator delete[](void* ptr, std::size_t size,
const std::nothrow_t&) noexcept; // ただし、備考を参照
- std::nothrow_t[link /reference/new/nothrow_t.md]
この機能を有効活用することで、メモリアロケータのパフォーマンスを向上できる可能性がある。
- サイズをとる
delete
演算子に渡されるsize
パラメータは、対応するnew
演算子に渡されたsize
パラメータと等しい - 型
T
が完全型でかつ、void*
をパラメータにとるdelete
演算子とvoid*
とstd::size_t
のパラメータにとるdelete
演算子の両方が定義されている場合、型T
のポインタに対するdelete
演算子の呼び出しはstd::size_t
をとるバージョンを呼び出す
#include <cstdio>
#include <cstdlib>
#include <new>
void* operator new[](std::size_t size)
{
std::printf("new size:%zu\n", size);
return std::malloc(size);
}
void operator delete[](void*) noexcept
{
std::printf("delete\n");
}
void operator delete[](void*, std::size_t t) noexcept
{
std::printf("delete with two arguments, %zu\n", t);
}
struct A {
~A() {} // デストラクタを明示的に定義しない場合、
// delete演算子が呼び出されない可能性がある
};
int main()
{
delete[] (new A[5]);
}
- std::printf[link /reference/cstdio/printf.md.nolink]
- std::malloc[link /reference/cstdlib/malloc.md.nolink]
new size:13
delete with two arguments, 13
- C++14 で追加された関数のうち、最後の引数が
const std::nothrow_t&
であるオーバーロード 2 つは、次期規格では削除される予定である。
これは、当該オーバーロードがnew
式、あるいはdelete
式から暗黙で呼び出される事は無いためである。 - Clangは3.7以降、サイズをとる
delete
演算子を使用する場合、-fsized-deallocation
オプションを付ける必要がある。