Вы с неинициализированной памятью работаете почти правильно, но…
Первое. Надо указать выравнивание класса.
MyClass* arr = (MyClass*) operator new (sizeof(MyClass) * 10,
std::align_val_t(alignof(MyClass)));
. . .
operator delete(arr, std::align_val_t(alignof(MyClass)));
Второе. А нельзя инкапсулировать подобную работу с памятью в класс, чтобы конструктор выделял память и деструктор отдавал? Я сделал вот такое.
#include <iostream>
class MyClass {
private:
const int a;
public:
MyClass() = delete;
MyClass(MyClass&&) = delete;
MyClass(const MyClass&) = delete;
MyClass(int a) : a(a) {};
~MyClass() = default;
MyClass& operator=(MyClass&&) = delete;
MyClass& operator=(const MyClass&) = delete;
operator int() const { return a; }
};
template <class T>
class DynArray {
public:
static constexpr std::align_val_t ALIGNMENT { alignof(T) };
DynArray (size_t n)
: maxSize(n),
d((T*) operator new (sizeof(T) * n, ALIGNMENT )) {}
~DynArray() {
std::destroy_n(d, currSize);
operator delete(d, ALIGNMENT);
}
template <class... Args>
T& add(Args&&... args);
T& operator [] (size_t i) { return d[i]; }
const T& operator [] (size_t i) const { return d[i]; }
private:
size_t currSize = 0, maxSize = 0;
T* d;
};
template <class T> template <class... Args>
T& DynArray<T>::add(Args&&... args)
{
if (currSize >= maxSize)
throw std::logic_error("[DynArray::add] Overflow");
auto& where = d[currSize++];
new (&where) MyClass(std::forward<Args>(args)...);
return where;
}
int main() {
DynArray<MyClass> da(10);
for (int i = 0; i < 10; ++i) {
da.add(i);
}
// Что-то сделали с массивом
for (int i = 0; i < 10; ++i) {
std::cout << da[i] << '\n';
}
return 0;
}
Ну и третье — в коде есть, но забыл указать — разбирайте API неинициализированной памяти Си++17.
ЧЕТВЁРТОЕ. Есть один класс, который не перемещает. Поскольку начиная с Си++17 весь STL внутри работает с неинициализированной памятью, получается довольно мило — но хранится ли оно непрерывно, мы никак не узнаем.
std::deque<MyClass> dq;
for (int i = 0; i < 10; ++i) {
dq.emplace_back(i + 42);
}
// Что-то сделали с массивом
for (int i = 0; i < 10; ++i) {
std::cout << dq[i] << '\n';
}