auto_ptr是一个大家都熟悉的模板类,它能实现较为方便的内存管理功能,而且是异常安全的。在某个项目中,我们需要实现一个能自动管理内存的类,大家知道auto_ptr是不能用在数组上的,而且,在对象的内存管理上,它也只限于确保对象内存能被释放,仅此而已。所以,我们需要自己写一个类。命名为SmartBuffer。
类的功能其实很简单,构造函数(ctro),拷贝构造函数(copy ctro),解构函数(dtro),赋值函数(operator =)大都参照auto_ptr编写,仅对数组处理作了修改。然后增加了一些额外的public函数,如往缓冲区添加数据(AddData),从缓冲区取数据(GetData),然后写了些对应的private函数供内部使用,如检查缓冲区是否够用,如不够则重新分配内存的函数(CheckBuffer)。
但在使用时发现有一个问题,如果我这么申明和定义拷贝构造函数:
SmartBuffer::SmartBuffer(SmartBuffer &sb)
{
m_pBuffer = sb.m_pBuffer;
sb = NULL;
}
和一个使用此类的函数
SmartBuffer Func()
{
SmartBuffer sb;
// 一些操作,产生的数据放在sb中
return sb;
}
以及对这个函数的使用:
SmartBuffer sb = Func();
但是,在Visual studio .net下上面的这行编译不通过。
要说明的是,我把vc中“配置属性”->“C/C++”->“语言”->“禁用语言扩展”给选上了,因为我要考虑到移植的问题,微软的扩展也许会带来一些问题。而如果这个选项关闭。问题就不存在了。
编译错误的提示是“无法把SmartBuffer转化为SmartBuffer”,各位也许会感到奇怪,怎么类自己都不能转化为自己?我当然也是感到非常的困惑,几经周折之后,我发现这个copy ctro有问题,它接受的是SmartBuffer &sb!而上面这个Func中,由于sb是一个临时变量,所以,需要调用的拷贝构造函数是SmartBuffer(const SmartBuffer &sb)。而const变量不能被修改。也就意味着我无法转移拥有权!为了对这个方案进行修补,我采取了较为野蛮的手段,就是直接用const_cast除去sb.m_pBuffer的const属性,也就达到了我的目的。
SmartBuffer::SmartBuffer(const SmartBuffer &sb)
{
m_pBuffer = sb.m_pBuffer;
char *p = const_cast (sb.m_pBuffer);
p = NULL;
}
然后,对operator = 我也作了相同的修改,防止出现类似的问题。
但问题是,这样的方案有没有缺陷?有没有更好的实现方法?望各位不吝赐教。
顺便说一下:STL中的auto_ptr,也是不能写出如:
auto_ptr Func()
{
auto_ptr ap(new myclass)
return ap;
}
这样的函数。
auto_ptr p = Func();
像这样调用的。
打开微软的语言扩展是可以编译通过的,但我不清楚微软到底做了哪方面的扩展,而且从语言的移植性上考虑,最好使用标准C++,尽量避免局限于某一种编译器上。
阅读(1033) | 评论(0) | 转发(0) |