好的,如果我想用自定义新运算符创建堆对象,我知道我需要像这样重载new
运算符:
void* operator new(size_t size, int unused)
{
void* ptr = malloc(size);
//some custom code
return ptr;
}
然后,如果我想使用这个重载的运算符创建一个堆对象,我会这样做:
SomeClass* a = new(0) SomeClass;
问题是:我可以做这样的事情来创建堆栈对象吗?
答案 0 :(得分: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;
}
答案 1 :(得分:1)
您可以像这样定义一个宏:
#define STACK_NEW(T) new (alloca(sizeof(T))) T
使用 placement new 和alloca()
在堆栈上分配块并在其上构造类型为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();
删除它们会有不确定的行为。
警告 :整个设施非常不安全。我强烈建议您不要在代码库中使用这种系统性危险的工具。据我所知,没有安全的方法可以使用它,会让你感到痛苦!