Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C+中不同大小的不同行为+;(Firebreath源代码)_C++_Templates_Firebreath - Fatal编程技术网

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

C++ C+中不同大小的不同行为+;(Firebreath源代码),c++,templates,firebreath,C++,Templates,Firebreath,在浏览firebreath()的源代码时,我遇到了一个困惑的问题 //函数指针表 结构fxn_ptr_表{ const std::type_info&(*get_type)(); 作废(*删除)(作废**); void(*克隆)(void*常量*,void**); 无效(*移动)(无效*常数*,无效**); 布尔(*减去)(无效*常数*,无效*常数*); }; //小值类型的静态函数 模板 结构fxns { 模板 结构类型{ 静态常量std::type_info&get_type(){ 返回类型

在浏览firebreath()的源代码时,我遇到了一个困惑的问题

//函数指针表
结构fxn_ptr_表{
const std::type_info&(*get_type)();
作废(*删除)(作废**);
void(*克隆)(void*常量*,void**);
无效(*移动)(无效*常数*,无效**);
布尔(*减去)(无效*常数*,无效*常数*);
};
//小值类型的静态函数
模板
结构fxns
{
模板
结构类型{
静态常量std::type_info&get_type(){
返回类型ID(T);
}
静态无效静态_删除(无效**x){
重新解释(x)->~T();
}
静态void克隆(void*const*src,void**dest){
新(目的地)T(*重新解释铸件(src));
}
静态无效移动(无效*常量*src,无效**dest){
重新解释(目标)->~T();
*重新解释铸件(目的)=*重新解释铸件(src);
}
静态布尔值(空*常数*左,空*常数*右){
TL(*重新解释铸造(左));
T r(*重新解释铸造(右));
返回l~T();
**重新解释铸件(目的地)=**重新解释铸件(src);
}
静态布尔值(空*常数*左,空*常数*右){
返回**重新解释投射(左)<**重新解释投射(右);
}
};
};
模板
结构获取表
{

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


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

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


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

内部文档怎么说?如果作者没有 记录在案,他可能不了解自己

从代码来看,与小对象的接口不同于 指向大对象的指针;传递给小对象的指针是 指向对象本身的指针,其中作为大 对象是指向指向该对象的指针的指针

然而,作者似乎不太清楚C++(我会)。 避免使用这样的代码)。例如,在
move
中 销毁对象,然后分配给它:这保证是未定义的 行为,并且除了最简单的 内置类型。小对象和大对象的区别很大程度上是 不相关;一些“小”对象可能非常昂贵 复制。当然,考虑到这里的所有内容都是一个模板,
绝对没有理由在任何事情上使用
void*

内部文档怎么说?如果作者没有 记录在案,他可能不了解自己

从代码来看,与小对象的接口不同于 指向大对象的指针;传递给小对象的指针是 指向对象本身的指针,其中作为大 对象是指向指向该对象的指针的指针

然而,作者似乎不太清楚C++(我会)。 避免使用这样的代码)。例如,在
move
中 销毁对象,然后分配给它:这保证是未定义的 行为,并且除了最简单的 内置类型。小对象和大对象的区别很大程度上是 不相关;一些“小”对象可能非常昂贵 复制。当然,考虑到这里的所有内容都是一个模板,
没有任何理由使用
void*

我已经编辑了你的问题,添加了原始源文件的链接,因为显然这里回答的大多数人没有阅读它来了解实际情况。我承认这可能是最令人困惑的部分之一
    // 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;
        }
    };