如何使用 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"回答这个问题。
例如有一条链
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"回答这个问题。