Callling对象构造函数/析构函数与自定义分配器 [英] Callling object constructor/destructor with a custom allocator

查看:174
本文介绍了Callling对象构造函数/析构函数与自定义分配器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找自定义分配器,我经常看到他们使用某种函数来分配内存。为了测试目的和进一步教育我的自我,我试图做一个简单的例子这样做。然而,我有一个基本的事情我明白如何做。在 malloc vs new 中的一个关键区别是,使用new调用了构造函数。如果我想写我自己的分配器基本上替换 new ,当使用 malloc

I have been looking into custom allocators and I quite often see them using some kind of function to allocate memory. For testing purposes and further educate my self, I tried to make a "simple" example of doing so. However, there is one fundamental thing I am understand on how to do. One of the key differences in malloc vs new is that with new the constructor is called. What if I wanted to write my own allocator that was essentially replacing new, how would I get the constructor to be called when using malloc?

我理解在类上我可以重载 new delete ,所以我想问题的一大部分是,在分配过程中如何 new 调用对象构造函数?同样,我对 delete 如何调用析构函数感兴趣。

I understand that on classes I can overload new and delete for the class, so I suppose a big part of the question is, how is new calling the objects constructor during allocation? Similarly, I am interested in how delete is calling the destructor.

我创建了一个示例测试代码,我希望在分配期间调用 SomeClass 构造函数,看不到。

I created a sample test code that I was hoping to have the SomeClass constructor called during allocation, but I don't see how.

#include <malloc.h>

void* SomeAllocationFunction(size_t size) {
    return malloc(size);
}

class SomeClass
{
public:
    SomeClass() {
        int con = 1000;
    }

    ~SomeClass() {
        int des = 80;
    }
};

int main(void){
    SomeClass* t = (SomeClass*)SomeAllocationFunction(sizeof(SomeClass));
    return 0;
}

(注意,我知道我可以使用 new 。但是,为了学习的目的,我试图创建一个自定义分配器,不仅仅是调用 new

(As a note, I know I can just use new. However, for the purposes of learning I am trying to create a custom allocator that does not just call new or placement new).

在本质上,当你使用一个新的表达式,例如

解决方案

c $ c> T * t = new T; ,大致相当于:

In essence, when you use a new expression like: T *t = new T;, it's roughly equivalent to:

void *temp = operator new(sizeof(T));
T *t = new(temp) T;

因此,首先使用分配函数分配一些原始内存,然后在该内存中构造一个对象。同样,当您使用如下的删除表达式: delete t; 时,大致相当于:

So, first it allocates some raw memory using the allocation function, then it constructs an object in that memory. Likewise, when you use a delete expression like: delete t;, it's roughly equivalent to:

t->~T();
operator delete(t);

因此,如果重载 new code> delete

So, if you overload new and delete for a particular class:

class T { 
    int data; 
public:
    // I've made these static explicitly, but they'll be static even if you don't.
    static void *operator new(size_t size) { 
        return malloc(size);
    }
    static void operator delete(void *block) { 
        free(block);
    }
};

然后当你使用一个新的表达式时,它会调用类'运算符new 分配内存,并且将调用 malloc ,因此 T * t = new T / code>将会通过 malloc (同样,当你 delete 将使用 operator delete ,将调用 free )。

Then when you use a new expression, it'll invoke the class' operator new to allocate the memory, and that will call malloc, so T *t = new T(); will end up allocating memory via malloc (and likewise, when you delete it, it'll use operator delete, which will call free).

至少作为通常使用的术语,分配器是非常相似的,除了它由容器使用而不是其他代码。它还将分配函数和删除函数封装到一个类中,因此当你将一个传递给容器时,你只需要传递一个对象,并且分配和删除函数不太可能不匹配。

At least as the term is normally used, an Allocator is quite similar, except that it's used by a container instead of other code. It also encapsulates the allocation function and deletion function into a class, so when you pass one to the container, you only have to pass one object, and there's little chance of an allocation and delete function getting mismatched.

暂时忽略用于什么名字的细节,标准库中的Allocator类大多是,这样做有点重命名函数在上面的 T 类中,你将要写一个标准分配器一半。要进行分配和删除,它有一个函数 rebind 一些内存(更改一个内存块到另一个类型),创建一个对象到位(基本上只是一个包装器围绕一个放置new)和销毁一个对象(再次,析构函数调用的琐碎包装)。当然,它使用 operator new operator delete 而不是 malloc free

Ignoring, for the moment, the details about what names are used for things, the Allocator class in the standard library mostly does the same, so with a little renaming of the functions in the T class above, you'd be about half done writing a standard allocator. To go with the allocation and deletion, it has a function to rebind some memory (change a block of memory to another type), create an object in place (basically just a wrapper around a placement new) and destroy an object (again, trivial wrapper around destructor invocation). Of course, it uses operator new and operator delete instead of malloc and free like I've used above.

这篇关于Callling对象构造函数/析构函数与自定义分配器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆