HUUYUU

写operator new和operator delete时要遵循常规

自己重写operator new时,很重要的一点是函数提供的行为要和系统缺省的operator new一致。实际做起来也就是:要有正确的返回值;可用内存不够时要调用出错处理函数;处理好0字节内存请求的情况。此外,还要避免不小心隐藏了标准形式的new。

非类成员形式的operator new的伪代码:

void * operator new(size_t size)        // operator new还可能有其它参数
{                                      

  if (size == 0)                      // 处理0字节请求时,
  {

        size = 1;                            // 把它当作1个字节请求来处理

  }                                    
  while (1)

{
    分配size字节内存;

      if (分配成功)
           return (指向内存的指针);

    // 分配不成功,找出当前出错处理函数
      new_handler globalhandler = set_new_handler(0);
     set_new_handler(globalhandler);

      if (globalhandler) (*globalhandler)();
      else throw std::bad_alloc();
  }
}

 

为特定类写的new往往没有考虑该类被继承的情况,使用sizeof(父类)获得大小,但是如果发生子类调用父类的new时,往往

会出错,子类的size往往大于父类的size。最好父类的new应该这么写:

void * base::operator new(size_t size)
{
  if (size != sizeof(base))                  // 如果数量“错误”,让标准operator new,精华部分。
    return ::operator new(size);        // 去处理这个请求
                                                         //

  ...                                                    // 否则处理这个请求
}

 

对于operator delete(以及它的伙伴operator delete[]),情况更简单。所要记住的只是,c++保证删除空指针永远是安全的,所以你要充分地应用这一保证。

下面是非类成员形式的operator delete的伪代码:
void operator delete(void *rawmemory)
{
  if (rawmemory == 0) return;   //如果指针为空,返回
                                 //

  释放rawmemory指向的内存;

  return;
}

 

这个函数的类成员版本也简单,只是还必须检查被删除的对象的大小。假设类的operator new将“错误”大小的分配请求转给::operator new,那么也必须将“错误”大小的删除请求转给::operator delete:

void base::operator delete(void *rawmemory, size_t size)
{
  if (rawmemory == 0) return;          // 检查空指针

  if (size != sizeof(base))                 // 如果size"错误",

{    
    ::operator delete(rawmemory);  // 让标准operator来处理请求
    return;                       
  }

  释放指向rawmemory的内存;

  return;
}

有关operator new和operator delete(以及他们的数组形式)的规定不是那么麻烦,重要的是必须遵守它。只要内存分配程序支持new-handler函数并正确地处理了零内存请求,就差不多了;如果内存释放程序又处理了空指针,那就没其他什么要做的了。至于在类成员版本的函数里增加继承支持,那将很快就可以完成。

posted on 2008-01-22 09:42 HUYU 阅读(399) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理