如何使用 malloc 通过基 class 的指针为派生 class 的对象分配内存?

How to allocate memory for object of the derived class by pointer of the base class using malloc?

例如有一条链

class A
{
int a;
int b;
public:
A();
};

class B: public A
{
int c;
char b;
public:
B()
};

以普通方式创建派生的对象class我们可以使用这种形式

A* ptr = new B()

如何使用 malloc 做同样的事情?

Malloc returns 指向原始分配内存的 void* 指针。只需在该内存上使用放置新运算符。

void* mem = malloc( sizeof(B) );
A* ptr = new(mem) B(); // builds object in location pointed by mem

placement new 不分配内存,它只是在给定的地方构造你的对象。

new 对 class 的实例进行两步构造。它分配堆内存,然后调用 class 的构造函数来初始化对象。

operator new(size_t size) 反过来只处理内存分配并且具有类似于 malloc() 的签名。它不调用实例的构造函数。

operator new(size_t size, void* ptr) 称为 placement new。它 returns ptr 在完全初始化实例之后,调用适当的构造函数。

如果您需要使用标准堆以外的其他类型的内存,您可以为您的 class 覆盖 operator new 和 placement new。如果您需要放置实例,比如放入线程本地存储、共享内存,或者如果您进行一些优化的数据结构,这会派上用场。此外,placement new 有时用于系统编程,将对象的实例放置在具有已知地址的某些寄存器集之上,以提供硬件接口的某种抽象。

因此,如果您 want/need 为您的实例使用 malloc(),您所要做的就是为您的 class 覆盖 operator new。并且可能不会忘记调用构造函数。

#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.
}

上面的代码示例显示了将 operator new() 用作 malloc() 替代品时的样子,表明它仅处理原始内存并且不依赖于 class 类型等。

要了解如何为您的 class 重载 operator new,请参见示例 here.

C 方法:

A* ptr = (A*)malloc(sizeof(B));
*(B*)ptr = B();

C++ 的实现方式:

A* ptr = static_cast<A*>(malloc(sizeof(B)));
*static_cast<B*>(ptr) = B();

请注意,由于我们使用的是 C++,因此我们必须转换 malloc 的 return 值。

由于"language mixture",没有"ANSI way"回答这个问题。