1

我想定义我自己的放置新和放置删除(采用额外参数),我发现我可以正确调用放置,而我无法访问放置删除。谁能告诉我是我错误地定义了展示位置删除还是我错误地调用了它?

class A
{
public:
    A( int a ) : a(a){}

    static void* operator new( std::size_t, int ); // the placement new
    static void operator delete( void*, int )throw(); // the corresponding placement delete
private:
    int a;
};

void* A::operator new( std::size_t size, int n )
{
    std::cout << "size: " << size << "  " << "n: " << n << std::endl;
    return ::operator new(size);
}

void A::operator delete( void* p, int n )throw()
{
    std::cout << "n: " << n << std::endl;
    ::operator delete(p);
}

int main( int argc, char* argv[] )
{
    A* a = new(10) A(100);

    std::cout << std::endl;

    delete(4) a; // error???????????????????, but how?

    return 0;
}
4

1 回答 1

5

布局delete仅可用于处理在评估布局new表达式期间发生的异常。如果构建成功完成,则稍后delete将使用正常。

您可以显式调用放置解除分配函数,但它的行为与delete运算符不同(它不会自动调用析构函数)。

在您的情况下,相应的代码将是:

a->~A();
A::operator delete(a, 4);

呸!

对于数组,情况更糟,因为您无法从编译器存储它以供自己使用的位置检索元素的数量(以及要调用的析构函数的数量)。

设计您的重载operator new,使其与 one-argument 正确配对operator delete。然后您班级的用户可以使用delete ptr;std::unique_ptr

如果您确实需要自定义解除分配,那么使用自定义删除器返回的分配包装器std::shared_ptr将比自定义放置 new 更好。

于 2013-07-15T14:34:09.230 回答