new
выполняет двухэтапную конструкцию экземпляра класса. Он выделяет кучную память, а затем вызывает конструктор класса для инициализации объекта.
operator new(size_t size)
в свою очередь касается только распределения памяти и имеет подпись, аналогичную malloc()
. Он не вызывает конструктор для экземпляра.
operator new(size_t size, void* ptr)
это место размещения новое. Он возвращает ptr после полной инициализации экземпляра, вызывая соответствующий конструктор.
Если вам нужно использовать другие типы памяти, кроме стандартной кучи, вы можете переопределить новый оператор и место размещения для вашего класса. Это пригодится, если вам нужно поместить экземпляр, скажем, в локальное хранилище потоков, разделяемую память или если вы создадите некоторые оптимизированные структуры данных. Кроме того, размещение new иногда используется в системном программировании, помещая экземпляр объекта поверх некоторого набора регистров с известным адресом, чтобы обеспечить некоторую абстракцию аппаратного интерфейса.
Итак, если вы хотите/должны использовать malloc() для своих экземпляров, все, что вам нужно сделать, это переопределить новый оператор для вашего класса. И, возможно, не забудьте вызвать конструктор.
#include <new>
A *ManuallyConstructBInstance()
{
B *pB = reinterpret_cast<B*>(operator new(sizeof(B)));
if(nullptr != pB)
{
new(pB) B(); // manual call of constructor using placement new.
}
return pB; // optionally use static_cast<A*>() if you want to emphasize the upcast.
}
В примере коды выше показано, как это выглядит, как если оператор новый() используются в качестве таНоса() заменителя, демонстрируя, что он имеет дело только с сырой памятью и не имеет incling по типам классов и т.д.
Чтобы узнать, как перегрузить новый оператор для вашего класса, см., Например, here.
В вашем коде B не является производным от A. – BitTickler
Спасибо, теперь исправлено. –
@ ՎարդանԳրիգորյան Почему вы используете 'malloc' вместо' new'? – PaulMcKenzie