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

时间:2015-03-30 06:53:29

标签: c++ inheritance malloc new-operator

例如,有一个链

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

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

以通常的方式创建派生类的对象,我们可以使用此表单

A* ptr = new B()

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

3 个答案:

答案 0 :(得分:4)

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

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

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

答案 1 :(得分:3)

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的返回值。

由于&#34;语言混合&#34;,没有&#34; ANSI方式&#34;回答这个问题。

答案 2 :(得分:2)

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

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

operator new(size_t size, void* ptr)称为展示位置新功能。它在完全初始化实例后返回ptr,调用相应的构造函数。

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

因此,如果您希望/需要为您的实例使用malloc(),您所要做的就是覆盖您的类的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()替换,它表示它只处理原始内存并且没有类型等等。

要了解如何为您的类重载operator new,请参阅示例 here