0

C++ 中的 AFAIK(或至少在我的编译器中:gcc 和 clang)允许使用以下代码:

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)类似的方式不适用于“删除”运算符。IE:

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

在“删除”行上给出一个硬错误。
有没有办法(可能是编译器开关)允许对
BLA::operator delete(bla, 3, 5) 进行这种非标准隐式调用?

使用上面的行真的会破坏好的语法:(

4

2 回答 2

2

无法将参数传递给删除运算符。在这里看到 Bjarne 的推理。重载删除(例如您正在实现的删除)仅在显式调用或相应的 new 抛出时使用。

如果您需要确保调用了正确的删除,那么您可以使用一个技巧。如果你只有两个 32 位 int 传递给构造函数,只需要多保留 64 位,并将这两个参数放在对象前面(你只需要在返回指针之前返回偏移的位置)。删除对象时,不要传递任何参数,而是从对象前面获取它们并使用它们来正确释放。这样您就可以使用不带参数的 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 - 必须传递参数来删除与你传递给 new 的匹配项似乎是一件非常危险的事情。我建议分配一点额外的空间,以便您可以存储i1和存放i2在其中。那么你的destroy函数根本不需要任何参数。

于 2012-04-23T19:14:56.783 回答