c++ - C++ 中不同大小的不同行为(Firebreath 源代码)

标签 c++ templates firebreath

我在查看firebreath ( src/ScriptingCore/Variant.h ) 的源代码时遇到了一个困惑的问题

    // function pointer table
    struct fxn_ptr_table {
        const std::type_info& (*get_type)();
        void (*static_delete)(void**);
        void (*clone)(void* const*, void**);
        void (*move)(void* const*,void**);
        bool (*less)(void* const*, void* const*);
    };

    // static functions for small value-types 
    template<bool is_small>
    struct fxns
    {
        template<typename T>
        struct type {
            static const std::type_info& get_type() { 
                return typeid(T); 
            }
            static void static_delete(void** x) { 
                reinterpret_cast<T*>(x)->~T(); 
            }
            static void clone(void* const* src, void** dest) { 
                new(dest) T(*reinterpret_cast<T const*>(src)); 
            }
            static void move(void* const* src, void** dest) { 
                reinterpret_cast<T*>(dest)->~T(); 
                *reinterpret_cast<T*>(dest) = *reinterpret_cast<T const*>(src); 
            }
            static bool lessthan(void* const* left, void* const* right) {
                T l(*reinterpret_cast<T const*>(left));
                T r(*reinterpret_cast<T const*>(right));

                return l < r;
            }
        };
    };

    // static functions for big value-types (bigger than a void*)
    template<>
    struct fxns<false>
    {
        template<typename T>
        struct type {
            static const std::type_info& get_type() { 
                return typeid(T); 
            }
            static void static_delete(void** x) { 
                delete(*reinterpret_cast<T**>(x)); 
            }
            static void clone(void* const* src, void** dest) { 
                *dest = new T(**reinterpret_cast<T* const*>(src)); 
            }
            static void move(void* const* src, void** dest) { 
                (*reinterpret_cast<T**>(dest))->~T(); 
                **reinterpret_cast<T**>(dest) = **reinterpret_cast<T* const*>(src); 
            }
            static bool lessthan(void* const* left, void* const* right) {
                return **reinterpret_cast<T* const*>(left) < **reinterpret_cast<T* const*>(right);
            }
        };
    };

    template<typename T>
    struct get_table 
    {
        static const bool is_small = sizeof(T) <= sizeof(void*);

        static fxn_ptr_table* get()
        {
            static fxn_ptr_table static_table = {
                fxns<is_small>::template type<T>::get_type
                , fxns<is_small>::template type<T>::static_delete
                , fxns<is_small>::template type<T>::clone
                , fxns<is_small>::template type<T>::move
                , fxns<is_small>::template type<T>::lessthan
            };
            return &static_table;
        }
    };

问题是为什么大值类型(大于 void*)的静态函数的实现与小值类型不同。

例如,对于小值类型,static_delete 只是调用 T 实例上的析构函数,而对于大值类型,则是使用'delete'。

有什么技巧吗?提前致谢。

最佳答案

看起来 Firebreath 为其小对象使用专用内存池,而大对象通常在堆中分配。因此,不同的行为。请注意 clone() 中用于小对象的位置 new,例如:这会在指定的内存位置创建新对象而不分配它。当您使用放置 new 创建一个对象时,您必须在释放内存之前显式调用它的析构函数,这就是 static_delete() 所做的。

内存实际上并没有被释放,因为正如我所说,它看起来像是一个专用的内存池正在使用中。内存管理必须在其他地方执行。这种内存池是常见的针对小对象的优化。

关于c++ - C++ 中不同大小的不同行为(Firebreath 源代码),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7955492/

相关文章:

c++ - 在模板中隐式获取字符串的长度

c++ - 如何给模板类添加常用功能?

c++ - boost.asio 在单线程和多线程进程中的复合操作

C++在构造函数中初始化一个非静态指针数组

c++ - ?另一个按钮的按钮功能

c++ - 如何简洁地初始化具有多个参数的模板函数?

c++ - 交叉编译 firebreath 目标窗口

wix - 无法在 WiX 安装程序中显示对话框

c++ - 在 firebreath 插件上创建子可编辑文本框窗口

c++ - 调用函数并在结构中传递值