Создание указателя объекта независимо от аргумента конструктора

Я пытаюсь создать вектор как контейнер Vector.

Затем заявил:

Vector< A> Avector.

При выделении памяти выдается ошибка компиляции, что у A нет конструктора по умолчанию.
Я написал следующий код для выделения памяти.

char *pBuffer = (char*) malloc(size*sizeof(T));
T *array;
for(int i = 0; i < size; i++)
{
(array+i) = new(pBuffer + i) T;
}
return array;

T — это переменная шаблона.

Ошибка связана с тем, что при размещении новых я использую конструктор по умолчанию для T, а я не написал конструктор по умолчанию для A.

Я хочу знать, есть ли способ, чтобы распределение памяти не зависело от сигнатуры конструктора.

0

Решение

В C ++ вызов new делает две вещи:

  1. Выделяет достаточно памяти для создаваемого объекта &
  2. Предоставляет возможность правильно инициализировать объект, вызывая его конструктор.

Это базовая конструктивная особенность C ++ как языка, pt 2 был добавлен, чтобы преодолеть malloc Поведение просто выделения памяти.

Короче говоря, вы не можете изменить это поведение.

2

Другие решения

Это не распределение памяти, которое зависит от сигнатуры конструктора. Это инициализация это делает.

Даже в вашем примере распределение выполняется malloc без вызова какого-либо конструктора. Это инициализация (выполняется путем размещения новой), которая требует использования конструктора.

Нет способа инициализировать пользовательский объект без вызова его конструктора.

Однако то, что вы можете сделать, по крайней мере в C ++ 11, — это поместить ваш код в функцию, которая принимает аргументы, необходимые вам для конструктора, в качестве rvalue-ссылок и передает их вызову конструктора в Placement-New. , Таким образом, вызывающая сторона вашей функции должна передать правильные аргументы. Если аргументы не передаются, вызывается конструктор по умолчанию.

Это на самом деле метод, используемый emplaceфункции нового std::vector:

template< class... Args >
void emplace_back( Args&&... args );

Это шаблон с переменным числом аргументов, поэтому возможно любое количество аргументов (ноль или более). Rvalue-ссылки используются для их получения, и внутри реализации вам придется вызывать конструктор, используя std::forward чтобы аргументы передавались как есть:

(array+i) = new (pBuffer + i) T(std::forward<Params>(args)...);

Таким образом, это все еще требует использования конструктора, но он оставляет за вызывающей стороной право выбора конструктора (путем выбора аргументов). Если конструктор по умолчанию недоступен, вызывающая сторона просто должна предоставить аргументы, необходимые для вызова конструктора не по умолчанию.

1

По вопросам рекламы [email protected]