如何重载新运算符以在堆栈上分配?

时间:2012-10-29 14:29:56

标签: c++ memory-management

如何为类类型重载new运算符,以便它在堆栈而不是堆上分配内存(基本上这样用户之后就不必调用delete)。

这样的事情:

class A{
    private:
        A(int i):
           this->i(i);
        {}
        A a;
        int i;

    public:
        void* operator new(size_t sz){
            a(12);
        }
};

上述解决方案是否有效?

4 个答案:

答案 0 :(得分:9)

不要!

使用自动存储...

new运算符旨在实现动态分配(您在堆上调用的内容),虽然您可以提供自己的分配器,但是您不能将其转换为遵守对象的作用域规则自动存储持续时间(您在堆栈中调用的内容)。

相反,写一下:

MyType myobject;  // automatic storage duration

...或智能指针......

或者,如果您不介意动态存储持续时间但 希望避免以后手动销毁,请使用智能指针:

std::unique_ptr<MyType> myptr(new myobject());  // unique, dynamic storage duration
std::shared_ptr<MyType> myptr(new myobject());  // shared, dynamic storage duration

这些都可以在C ++ 11(std::)和Boost(boost::)中找到。

...或展示位置new

另一种方法可能是贴装新,但这是一条黑暗而危险的旅行路径,我在此阶段肯定不会推荐。或者,坦率地说,任何阶段......你通常仍然需要手动破坏。你所获得的只是使用关键字new,这似乎毫无意义。

答案 1 :(得分:1)

为什么不只是自动变量(它是“在堆栈上”而不需要手动调用析构函数:

int foo() {
  A a;
  int i;
  ...
  // don't need to call delete

}


要按字面意思回答你的问题,有一个新的位置,它从用户那里获取内存 - 所以你可以将这个内存作为自动缓冲区:

  alignas(int) char buffer[sizeof(int)];
  int* p = new (buffer) int;
  //           ^^^^^^^^

对于非POD对象 - 您不需要调用delete - 但是您必须手动调用析构函数:

  class A { public: ~A(){} };
  alignas(A) char buffer[sizeof(At)];
  A* p = new (buffer) A;
  //         ^^^^^^^^
  p->~A();

alignas是C ++ 11中的新功能 - 在C ++ 03中,你必须以不同的方式处理正确的对齐。必须从new返回正确对齐的内存 - 否则行为未定义。

答案 2 :(得分:1)

我认为这里的好答案是:

不要重新调整operator new。

如果仍然希望通过这条道路,您可以查看this question

如果没有,您可以随时使用智能指针或共享指针,以避免用户必须删除已分配的内存。

答案 3 :(得分:0)

看来你不知道你在问什么。根据定义,new运算符在堆上分配内存。要在堆栈上创建对象,只需将其声明为局部变量。

看看实际想要做什么,你说你认为这会很棒的原因是:

  

基本上这样用户之后不必再调用删除

该功能是使用smart pointers实现的。我强烈建议你把时间花在学习上。