ezus, я отнюдь не уверен, что ты вполне понимаешь последствия. Placement new использует кусок памяти по данному ему адресу. Но этот вовсе не значит, что объект внутри устроен исключительно как массив чисел. Та может быть и служебная информация, таблицы виртуальных функций и т.д. Т.е. placement new - это не магическое отображение на поля. И эта халява может дорого стоить.
Пример:
#include <algorithm>
#include <iostream>
using namespace std;
class A
{
private:
int x;
public:
A() : x(3) {}
};
class B
{
private:
int x;
public:
B() : x(5) {}
virtual void f() {}
};
void print(const int *buf, const int n, const char *msg)
{
cout << msg << ": ";
for(int i = 0; i < n; ++i)
{
cout << buf[i] << " ";
}
cout << endl;
}
int main()
{
const int n = 10;
int buf[n];
fill(buf, buf + n, 0);
print(buf, n, "Free");
A *a = new (static_cast<void *>(buf + 1)) A();
print(buf, n, "A created");
B *b = new (static_cast<void *>(buf + 3)) B();
print(buf, n, "A and B created");
return 0;
}
Free: 0 0 0 0 0 0 0 0 0 0
A created: 0 3 0 0 0 0 0 0 0 0
A and B created: 0 3 0 134515264 5 0 0 0 0 0
Как видишь, объекты A и B содержат лишь одно поле int, в котором должны быть числа 3 и 5. И эти числа появляются в буфере. Но ещё в буфере появляется указатель на виртуальную функцию f объекта B.
Наконец, все эти подходы никак не позволяют управлять созданием и уничтожением объектов - тебе придётся дополнительно делать менеджер памяти, который непременно будет содержать списки занятых и свободных областей. Достигнешь ли ты этим экономии памяти - не уверен. В лучшем случае, если объекты уничтожаются как стек или очередь, можно будет обойтись без списков лишь одним/двумя указателями внутри буфера.
P.S. Но я вообще полагал, что ты используешь массив для хранения данных, т.е. для работы с этим нужны шаблоны проектирования вроде "посетителя" (visitor) и "приспособленца" (flyweight). Т.е. нужен такой объект, который похож на курсор в базах данных: получает указатель на кусок массива, и дальше знает, какую структуру имеют числа, начинающиеся с этого указателя.