08項 operator newとoperator deleteを書くときは規約を守ろう

"operator newとoperator deleteを書くときは規約を守ろう"

new,deleteをオーバロードするときには、規約を守る必要があります。


まずはnewの基本の規約3つ
1,正しい戻り値を返す。
2,メモリが不足したときにエラー処理関数を呼び出す。それでもだめなら例外を投げる。
3,通常のnewを隠ぺいしない。

さらに注意すべき点として、newに0バイトが要求された場合の対応、ユーザ定義のoperator newが継承された場合があります。


本書では、newに0バイトが要求された場合に1バイトを割り当てるという対応を取っています。

static void *operator new(size_t size)
{
	if(size == 0)
		size = 1;
	...
}


ユーザ定義のoperator newが継承された場合は、標準のnewを呼び出すという対応を取っています。

static void *operator new(size_t size)
{
	if(size != sizeof(BASE)) //基本クラスと派生クラスのサイズが違うので、この式で判別できる。
		return ::operator new(size);
	...
}

ただし、本書に書かれている継承時の対応は、配列のnewには適用できません



delete、delete []を書くときに必ず守らなければいけない規約は、NULLを削除しても常に安全を保つということです。
本書には以下のコードが書かれています。

void operator delete(void *rawMemory)
{
	if(rawMemory == NULL)
		return ;
	...
}

newと同じように、継承されたクラスに対応するために、delete内で継承の判別をしなくてはなりません。

static void operator delete(void *rawMemory, size_t size)
{
	if(rawMemory == NULL)
		return ;
	if(size != sizeof(BASE))
	{
		::operator delete(rawMemory);
		return ;
	}
	...
}