メンバーoperator new
/delete
は、たとえば、ベースが拡張されることを意図していない場合に、ベースクラスから望ましくないカスタム割り当てを削除するのに役立つ場合があります。ただし、ベースには仮想デストラクタが必要であるか、ベースオブジェクトがのサブジェクトであってはなりませんdelete
。
実際には、の仮想デストラクタディスパッチはoperator delete
、オーバーロードとは関係なく必要です。この機能はおそらく多重継承をサポートするために存在し、正しいメンバーを動的に見つけることoperator delete
は単なる副作用です。
ルールは、最も派生したオブジェクトの仮想デストラクタがを呼び出すということoperator delete
です。主な理由は、最も派生した正しいポインタとサイズを渡すことです。コンテキストによって、プログラムが正しい割り当て解除関数を動的に見つけることもできるというのは、嬉しい副作用です。
したがって、動的ディスパッチに役立つアプリケーションがある場合とない場合がありますが、delete
それを機能させるための専用のメカニズムは絶対にありません。
簡単なデモ:
struct pad {
int x;
virtual ~pad() {}
};
struct b {
int x;
};
struct vb {
int x;
virtual ~vb() {}
};
struct d : pad, b, vb {};
void operator delete( void *p ) {
std::cout << "free " << p << '\n';
}
int main() {
std::cout << "With virtual destructor:\n";
d *p = new d;
std::cout << "allocate " << p << ", delete " << static_cast< vb * >( p ) << '\n';
delete static_cast< vb * >( p );
std::cout << "With plain destructor:\n";
p = new d;
std::cout << "allocate " << p << ", delete " << static_cast< b * >( p ) << '\n';
delete static_cast< b * >( p );
}