强制隐式调用非标准删除操作符函数

时间:2012-04-23 18:51:51

标签: c++ delete-operator

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)类似的方式不适用于'delete'运算符。即:

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)?

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

2 个答案:

答案 0 :(得分:2)

无法将参数传递给delete运算符。看到Bjarne对此here的推理。重载删除(例如您正在实现的删除)仅在explicetly或相应的新throws时使用。

如果您需要确保调用正确的删除,可以使用一些技巧。如果只有两个32位整数传递给构造函数,只需保留64位以上,并将这两个参数放在对象前面(只需要在返回指针之前返回偏移位置)。删除对象时,不要传递任何参数,而是从对象前面获取它们并使用它们正确解除分配。这样您可以使用不带参数的删除,并且可以确保正确地释放每个对象。

不确定以下内容是否会被视为系统中的错误:

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

即。如果可以与分配不同地解除分配,则此方法将不起作用。如果以不同方式解除分配是危险的,那么通过明确地保存参数这种方式实际上更安全。

答案 1 :(得分:2)

Stroustrup在讨论C ++中缺少“放置删除”时提及something that's probably helpful

您可以编写自己的销毁功能,而不是自定义删除功能。

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函数根本不需要任何参数。