C++自定义布局新的和放置删除调用

C++自定义布局新的和放置删除调用,c++,placement-new,placement,C++,Placement New,Placement,我想使用额外的参数定义我自己的placement new和placement delete,我发现我可以正确调用placement,而无法访问placement delete。有人能告诉我我是否定义了不正确的位置删除或调用了不正确的位置删除吗 class A { public: A( int a ) : a(a){} static void* operator new( std::size_t, int ); // the placement new static vo

我想使用额外的参数定义我自己的placement new和placement delete,我发现我可以正确调用placement,而无法访问placement delete。有人能告诉我我是否定义了不正确的位置删除或调用了不正确的位置删除吗

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;
}
Placement delete仅可用于处理在计算Placement new表达式期间发生的异常。如果施工成功完成,则稍后将使用正常删除

您可以显式调用placement-deallocation函数,但它的行为与delete运算符不同,它不会自动调用析构函数

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

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

对于数组,情况更糟,因为您无法从编译器为自己使用而存储的位置检索要调用的元素数和析构函数数

设计重载运算符new,使其与一个参数运算符delete正确配对。然后类的用户可以使用delete ptr;和std::独特的ptr等

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

placement delete仅可用于处理placement new表达式求值期间发生的异常。如果施工成功完成,则稍后将使用正常删除

您可以显式调用placement-deallocation函数,但它的行为与delete运算符不同,它不会自动调用析构函数

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

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

对于数组,情况更糟,因为您无法从编译器为自己使用而存储的位置检索要调用的元素数和析构函数数

设计重载运算符new,使其与一个参数运算符delete正确配对。然后类的用户可以使用delete ptr;和std::独特的ptr等


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

此配置的可能副本看起来不像新位置,特别是你实例化A*指针的方式,不确定10是一个正确的内存位置:P.看看这里:@Xaqq:这是一种新的布局形式,但这并不是最常见的一个传入对象将被放置的地址的方法。我更喜欢不使用new和delete,而是定义适当的构造函数/析构函数-即使它有效,但事实并非如此,如果A*A=new A的行为与类A的构造函数完全不同,这将非常令人困惑,构造函数的参数a与成员变量a的名称相同。永远不要落入将参数命名为成员变量的陷阱。如果你对你的编译器撒谎,它可能会相信你。这个可能的副本看起来不像是新的位置,特别是你实例化A*指针的方式不确定10是一个正确的内存位置:P.看看这里:@Xaqq:这是一种新的位置形式,但这并不是最常见的一个传入对象将被放置的地址的方法。我更喜欢不使用new和delete,而是定义适当的构造函数/析构函数-即使它有效,但事实并非如此,如果A*A=new A的行为与类A的构造函数完全不同,这将非常令人困惑,构造函数的参数a与成员变量a的名称相同。永远不要落入将参数命名为成员变量的陷阱。如果你对你的编译器撒谎,它可能会相信你。这是否意味着我不能更改placement delete的签名,我只能重新定义它?当我想释放资源时,我会调用:a->~a;删除一个@JavaBeta:否。删除a;将再次调用析构函数,然后调用单参数释放函数运算符deletevoid*。如果您想调用不同的placement-deallocation函数,请按照我的答案显式执行。如果你能使普通的释放函数正常工作,那么你的类的用户可以说只是删除p;同时获取析构函数调用和释放。哦,我必须通过作用域操作符显式地调用它?它可以工作,但仍然让我感到困惑,无论如何,placement new和placement delete调用机制是不一致的。@JavaBeta:这是因为您不打算使用placement delete。它就在那里,你们可以使用它,但由于技术原因,请看这个问题的评论中的链接,它不是无缝的。是的,我想我再次混淆了运算符delete和delete表达式。谢谢your@BenVoigt即时和有用的评论!这意味着我不能更改placement delete的签名,只能重新定义它吗?当我想发布
资源,我称之为:a->~a;删除一个@JavaBeta:否。删除a;将再次调用析构函数,然后调用单参数释放函数运算符deletevoid*。如果您想调用不同的placement-deallocation函数,请按照我的答案显式执行。如果你能使普通的释放函数正常工作,那么你的类的用户可以说只是删除p;同时获取析构函数调用和释放。哦,我必须通过作用域操作符显式地调用它?它可以工作,但仍然让我感到困惑,无论如何,placement new和placement delete调用机制是不一致的。@JavaBeta:这是因为您不打算使用placement delete。它就在那里,你们可以使用它,但由于技术原因,请看这个问题的评论中的链接,它不是无缝的。是的,我想我再次混淆了运算符delete和delete表达式。谢谢your@BenVoigt即时和有用的评论!