このページはC++14に採用された言語機能の変更を解説しています。
のちのC++規格でさらに変更される場合があるため関連項目を参照してください。
概要
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から追加(ただし、備考を参照)
追加分の詳細なインタフェースは、以下のようになっている:
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; // ただし、備考を参照
この機能を有効活用することで、メモリアロケータのパフォーマンスを向上できる可能性がある。
仕様
- サイズをとる
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]);
}
出力
new size:13
delete with two arguments, 13
備考
- C++14 で追加された関数のうち、最後の引数が
const std::nothrow_t&
であるオーバーロード 2 つは、次期規格では削除される予定である。
これは、当該オーバーロードがnew
式、あるいはdelete
式から暗黙で呼び出される事は無いためである。 - Clangは3.7以降、サイズをとる
delete
演算子を使用する場合、-fsized-deallocation
オプションを付ける必要がある。