C++ C+中不同大小的不同行为+;(Firebreath源代码)
在浏览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(){ 返回类型
//函数指针表
结构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
例如,对于小对象:这将在指定的内存位置创建新对象,而不分配它。当您使用placementnew
创建对象时,必须在释放内存之前显式调用该对象上的析构函数,这就是static\u delete()
所做的
内存实际上没有被释放,因为正如我所说,它看起来像一个专用内存池正在使用。内存管理必须在其他地方执行。这种内存池是小对象的常见优化。看起来Firebreath为其小对象使用一个专用内存池,而大对象则被正常分配因此不同的行为。请注意clone()中的位置new
例如,对于小对象:这将在指定的内存位置创建新对象,而不分配它。当您使用placementnew
创建对象时,必须在释放内存之前显式调用该对象上的析构函数,这就是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;
}
};