首页 > 解决方案 > 模板化放置 new - 调用析构函数

问题描述

我正在使用模板和新位置创建自己的矢量实现。

(如果你想知道为什么我要创建一个向量实现,当 C++ 库已经有一个时,那是因为我mmap在它下面有我自己的基于内存分配器,我需要其他原因。)

下面的代码只是一个人为的例子——我的向量实现使用的实际内存缓冲区是从我的内存分配器提供的,但是在这里我只是做了一个“char *pBuffer”来表示它,但是会有一个底层的“实际上处理分配/解除分配/重新分配的缓冲区”类 - 只关注我遇到的问题的本质:

template <typename Type> class Vector
{
    private:
        char *          pBuffer;

    public:
        Vector()
        {
            pBuffer = new char[sizeof(Type) * 100];
        }
        
        Type *create(int index)
        {
            Type *ptr = reinterpret_cast<Type *>(pBuffer);
                
            Type *item = new (&ptr[index]) Type();
            
            return item;
        }
        
        void remove(int index)
        {
            Type *ptr = reinterpret_cast<Type *>(pBuffer);
            
            Type *item = &ptr[index];
            
            item->~Type();
        }
        
        ~Vector()
        {
            delete pBuffer;
        }        
}

但是,当我通过调试器运行此代码时,它只是跳过了“item.~Type();” 好像它不存在一样(单步直接跳过它),并且不调用析构函数。

就好像编译器(GCC 7.5)将其视为空语句,忽略它甚至不编译它。在 GDB 中单步运行时,就好像对析构函数的调用甚至不存在一样。并且没有调用析构函数。

由于我正在使用placement new - 将此向量映射到另一个类处理的一些已分配内存之上mmap- 然后我需要能够调用Type's 析构函数以确保所有内容都被正确释放和清理。

如果我调用模板:

Vector<Track> tracks;

那么需要调用的析构函数实际上是命名为“~Track()”而不是“~Type()”,但是因为它是一个模板并且使用了placement new,所以我需要调用提供给模板以正确解构类型。但是模板语法肯定会自动将“~Type()”视为“提供给模板的类型的析构函数”并相应地重命名它?

是否有某种我没有包含的语法让编译器知道,不,真的,你必须调用析构函数,你不能忽略它或优化它?

编辑:修复了代码示例中的愚蠢错误。

标签: c++gccdestructornew-operatorplacement-new

解决方案


推荐阅读