伙计们,
当在类层次结构上使用allocation new时,基类必须执行去分配。否则,将对取消分配的对象调用基类析构函数.我希望能够从派生类执行去分配。因此,我开放的想法和建议!(注意:我没有结婚安置-新的,但我想有自定义内存管理,而不是新/删除)。
请在下面找到代码示例:
#include <cstdint>
#include <cstdio>
#include <new>
class CParent
{
public :
CParent() {
printf("CParent()\n");
}
virtual ~CParent() {
printf("~CParent()\n");
}
};
class CAllocator
{
private :
void Free(uint8_t *buffer) {
printf("CAllocator::Free(%p)\n", buffer);
delete [] buffer;
}
class CChild : public CParent
{
public :
CChild(CAllocator &allocator, uint8_t *buffer)
: mAllocator(allocator), mBuffer(buffer)
{
printf("CChild()\n");
}
~CChild() {
printf("~CChild()\n");
mAllocator.Free(mBuffer);
}
private :
CAllocator &mAllocator;
uint8_t *mBuffer;
};
public :
CParent *Alloc() {
uint8_t *buffer = new uint8_t[sizeof(CChild)];
printf("CAllocator::Alloc() = %p\n", buffer);
return new (buffer) CChild(*this, buffer);
}
};
int main()
{
CAllocator allocator;
CParent *object = allocator.Alloc();
// NB: Can't do `delete object` here because of placement-new
object->~CParent();
return 0;
}它提供了以下输出:
CAllocator::Alloc() = 0x2001010
CParent()
CChild()
~CChild()
CAllocator::Free(0x2001010)
~CParent()所以在内存释放后调用~CParent() ..。非常感谢你的帮助!
发布于 2015-05-20 16:52:47
你把下面的概念混合在一起,让我觉得你不清楚它们应该是什么:
new算子当您使用普通的旧operator new分配对象时,会发生两件事:
当对由operator delete返回的指针调用operator new时,会发生两种情况:
使用placement new运算符时,必须:
new运算符之前分配内存。new时使用预先分配的内存。调用类的构造函数来初始化对象。对于这些对象,您必须:
operator new char[size];分配内存,则使用delete [] ptr;来释放内存。如果使用malloc(size)分配内存,则使用free(ptr)来释放内存。为了保持代码的整洁,您应该将以下内容分开:
在您发布的代码中,类CChild似乎是不干净的。还不清楚它是用于帮助您管理内存的面向类的用户还是帮助您管理内存的助手类。
如果您想让它成为一个面向类的用户,我会将代码重构为:
#include <cstdint>
#include <cstdio>
#include <new>
class CParent
{
public :
CParent() {
printf("CParent()\n");
}
virtual ~CParent() {
printf("~CParent()\n");
}
};
class CChild : public CParent
{
public :
CChild()
{
printf("CChild()\n");
}
~CChild() {
printf("~CChild()\n");
}
private :
};
class CAllocator
{
public :
void Free(uint8_t *buffer) {
printf("CAllocator::Free(%p)\n", buffer);
delete [] buffer;
}
uint8_t *Alloc(size_t size) {
uint8_t *buffer = new uint8_t[size];
printf("CAllocator::Alloc() = %p\n", buffer);
return buffer;
}
};
int main()
{
CAllocator allocator;
uint8_t *buffer = allocator.Alloc(sizeof(CChild));
CParent* object = new (buffer) CChild;
object->~CParent();
allocator.Free(buffer);
return 0;
}如果您打算将CChild用作管理内存的助手类,那么首先要做的是确保CAllocator::Alloc()和CAlloctor::Free()是对称的。由于Alloc()返回指向CParent的指针,因此需要更改Free()以接受指向CParent的指针并对其执行正确的操作。下面是我认为代码应该是什么样子:
#include <cstdint>
#include <cstdio>
#include <new>
class CParent
{
public :
CParent() {
printf("CParent()\n");
}
virtual ~CParent() {
printf("~CParent()\n");
}
};
class CAllocator
{
private :
class CChild : public CParent
{
public :
CChild(uint8_t *buffer) : mBuffer(buffer)
{
printf("CChild()\n");
}
~CChild() {
printf("~CChild()\n");
// The object has ownership of the buffer.
// It can deallocate it.
delete [] mBuffer;
}
private :
uint8_t *mBuffer;
};
public :
// Make Alloc and Free symmetric.
// If Alloc() returns a CParent*, make sure Free()
// accepts the same value and does the right thing
// with it.
CParent *Alloc() {
uint8_t *buffer = new uint8_t[sizeof(CChild)];
printf("CAllocator::Alloc() = %p\n", buffer);
// Transfer the ownership of buffer to CChild
return new (buffer) CChild(buffer);
}
void Free(CParent* object) {
printf("CAllocator::Free(%p)\n", object);
object->~CParent();
}
};
int main()
{
CAllocator allocator;
CParent *object = allocator.Alloc();
allocator.Free(object);
return 0;
}https://stackoverflow.com/questions/30354497
复制相似问题