0

好的,如果我想使用自定义的 new 运算符创建堆对象,我知道我需要new像这样重载运算符:

void* operator new(size_t size, int unused)
{
    void* ptr = malloc(size);
    //some custom code
    return ptr;
}

然后,如果我想使用这个重载运算符创建一个堆对象,我会这样做:

SomeClass* a = new(0) SomeClass;

问题是:我可以做这样的事情来创建一个堆栈对象吗?

4

2 回答 2

2

我同意其他答案,你可能不需要这个,但你可以做到。请参阅下面的示例代码,只需提前分配内存并将其传递给placement new。如果您使用数组 new[] 形式,您可能想要执行此操作,您可能会执行类似的操作

void *rawMemory = operator new[](25*sizeof(std::stack));

如果你有一个堆栈数组,你有一个管理资源或其他东西的工厂方法。无论哪种方式,它都取决于您的应用程序和用例。下面是一个简单的例子

  #include <iostream>
#include <stack>

int main ( int argc, char *argv[])
{
  void *rawMemory = operator new(sizeof(std::stack<unsigned int>));
  std::stack<unsigned int> *s = new (rawMemory) std::stack<unsigned int>;

  s->push(10);

  std::cout << s->top() << std::endl;

  return 0;
}

第二个使用数组版本的示例,在您可能管理 25 个不同的堆栈并将它们交给客户的情况下,这似乎更有用。另外,回答您的评论。看到这次容器是在堆栈定义中定义的,在这种情况下我使用容器的向量。Stack 是一个容器,但它有一个默认为 deque 的底层容器

#include <iostream>
#include <stack>
#include <vector>

int main ( int argc, char *argv[])
{
  typedef std::stack<unsigned int,std::vector<unsigned int> > StackType;

  void *rawMemory = operator new[](25*sizeof(StackType));

  StackType *stacks = static_cast<StackType*> (rawMemory);

  // allocate
  for ( unsigned int i = 0; i < 25; ++i )
  {
    new (stacks+i) StackType;
  }

  stacks[1].push(10);
  std::cout << stacks[1].top() << std::endl;

  // don't forget to delete or smart resize
  for ( int i = 24; i >= 0; --i )
  {
    StackType x;
    std::swap ( x, stacks[i] );
  }

  return 0;
}
于 2013-08-18T08:57:42.767 回答
1

你可以像这样定义一个宏:

#define STACK_NEW(T) new (alloca(sizeof(T))) T

它使用placement newalloca()在堆栈上分配一个块并在其T顶部构造一个类型的对象。您还可以定义数组版本:

#define STACK_NEW_ARRAY(T, n) new (alloca(n * sizeof(T))) T

您可以通过以下方式使用此宏:

int * p = STACK_NEW(int);
MyObj * q = STACK_NEW(MyObj) (my, constructor, parameters);
int * r = STACK_NEW_ARRAY(int, 42);

您将手动破坏这些对象:

q->~MyObj();

删除它们将具有未定义的行为。

警告:整个设施非常不安全。我强烈建议不要在你的代码库中使用这种系统性危险的工具。据我所知,没有安全的使用方法,它会给你带来痛苦!

于 2013-08-18T09:03:22.007 回答