0

C ++(または少なくとも私のコンパイラ:gccとclang)でのAFAIKでは、次のコードが許可されています。

struct BLA { void *operator new( std::size_t size, int i1, int i2 ); };

int main( void )
{
    struct BLA *bla = new (3,5) BLA;
    return 0;
}

IMAOこれは、ストレージを割り当てる非常にクリーンな構文を可能にするため、非常に優れています。
この手法を使用すると、オブジェクトを非常にクリーンな方法で割り当てる方法に起因する変数を渡すことができ、コンストラクターを悪用する必要がなくなります。
残念ながら、C ++標準では(AFAIK)、「削除」演算子では同様の方法は機能しないとされています。すなわち:

struct BLA
{
    void *operator new( std::size_t size, int i1, int i2 );
    void operator delete( void *p, int i1, int i2 );
};

int main( void )
{
    struct BLA *bla = new (3,5) BLA;
    delete (3,5) bla;
    return 0;
}

'delete'行にハードエラーが発生します。 BLA :: operator delete(bla、3、5
)へのこの非標準の暗黙の呼び出しを許可する方法(おそらくコンパイラスイッチ)はありますか?

上記の行を使用すると、素晴らしい構文が本当に破壊されます:(

4

2 に答える 2

2

削除演算子に引数を渡す方法はありません。これについてのBjarneの推論をここで見ました。実装しているようなオーバーロードされた削除は、明示的に呼び出された場合、または対応する新しいスローが発生した場合にのみ使用されます。

正しい削除が呼び出されていることを確認する必要がある場合でも、使用できるトリックがあります。コンストラクターに渡される32ビットintが2つしかない場合は、必要以上に64ビットを予約し、これら2つのパラメーターをオブジェクトの前に配置します(ポインターを返す前にオフセット位置を返す必要があります)。オブジェクトを削除するときは、パラメータを渡さないでください。代わりに、オブジェクトの前からパラメータをフェッチし、それらを使用して正しく割り当てを解除してください。このようにして、パラメーターなしでdeleteを使用でき、各オブジェクトの割り当てが正しく解除されていることを確認できます。

以下がシステムのバグと見なされるかどうかわからない:

struct BLA *bla = new (3,5) BLA;
delete (4,6) bla;

つまり、割り当てとは異なる方法で割り当てを解除できる場合、この方法は機能しません。別の方法で割り当てを解除するのが危険な場合は、パラメータを明示的に保存するこの方法よりも実際にははるかに安全です。

于 2012-04-23T19:06:46.803 に答える
2

Stroustrupは、C++での「配置削除」の欠如を議論するのにおそらく役立つ何かに言及しています。

削除をカスタマイズするのではなく、独自の破棄関数を作成できます。

struct BLA {
  void *operator new( std::size_t size, int i1, int i2 );
  void destroy( int i1, int i2 );
private:
  ~BLA(); // private so you can't call regular delete
};

void BLA::destroy( int i1, int i2 ) {
  this->~BLA(); // explicit destructor call
  // your custom deallocation code
}

FWIW-新規に渡したものと一致するパラメータを削除するために渡さなければならないことは、非常に危険なことのように思われます。収納できるように少し余裕を持たせることをお勧めi1i2ます。そうすれば、destroy関数はパラメータをまったく必要としないはずです。

于 2012-04-23T19:14:56.783 に答える