0

我希望能够“以某种方式”创建一个动态数组,它仍然可以让我使用 new 运算符构建它的元素。这是我想要实现的目标:

A* a = new A[3]; //or any equivalent syntax 
new (&a[0]) A(myparams1); //placement new on first slot 
new (&a[1]) A(myparams2, ...); //placement new on 2nd slot 
new (&a[2]) A(myparams3, ...); //placement new on 3rd slot
delete[] a; //correct deletion of all elements

我知道这段代码可以工作(减去覆盖的 3 个元素),但我想避免a在第一次调用new[]. 我在这里假设我总是在调用之前放置 3 个元素delete[]。我在想这样的事情可以通过使用智能调用来实现,A::operator new[]但我不确定如何。有谁有想法吗?主要是出于好奇

4

3 回答 3

3

你只是得到原始内存:

void* mem = ::operator new(capacity * sizeof(A));

任何类型都需要对齐,包括A's 数组。现在您可以在其中构建:

for (std::size_t i = 0; i < capacity; ++i)
{
    void* addr = static_cast<char*>(mem) + i * sizeof(A);
    new (addr) A(x, y, z, ...);
}

破坏需要你显式调用它:

for (std::size_t i = 0; i < capacity; ++i)
{
    void* addr = static_cast<char*>(mem) + i * sizeof(A);
    static_cast<A*>(addr)->~A();
}

现在您可以释放原始内存:

::operator delete(mem);

请注意,这些都不是异常安全的。这也是什么std::vector<A>,检查代码。

于 2012-05-11T22:09:00.820 回答
2

使用运算符 new。

A a* = (A*) ::operator new(sizeof(A) * 3);
new (&a[0]) A(/* whatever */);
//do stuff
a[0].~A();
::operator delete(a);

请注意手动调用析构函数。使用placement new 时,不会自动调用析构函数,因此由您决定。

于 2012-05-11T22:07:16.163 回答
1

您可以创建指针数组。

A ** a = new A*[3]
a[0] = new A;
a[1] = new A;
a[2] = new A;

您需要调用delete每个分配的元素

delete a[2];
delete a[1];
delete a[0];

并删除数组本身delete[] a;

于 2012-05-11T22:17:25.147 回答