我在查看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/