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 ; } ... }