vector里存对象指针时大家都怎么做,我是这么弄的,求意见

glacier3d 2010-04-24 02:38:26
如题,auto_ptr肯定是不行的,我是弄了个smart_ptr来存指针,具体是参考一些资料改的。


template <class T>
class smart_ptr
{
private:
class ref_counter
{
public:
ref_counter(T* p){ count = 0; ptr = p; }
void addRef(){ count++; }
void release(){ count--; if(count <= 0) destroy(); }
T* getPtr() const{ return ptr; }
private:
~ref_counter(){ if(ptr) delete ptr; }
void destroy(){ delete this; }
int count;
T* ptr;
};
public:
smart_ptr(){ refcount = NULL; }
smart_ptr(T* p){ refcount = NULL; reset(p); }
smart_ptr(const smart_ptr& sp){ refcount = NULL; reset(sp.refcount); }
~smart_ptr(){ reset((ref_counter*)NULL); }
T* get(){ return (refcount==NULL) ? NULL : refcount->getPtr(); }
void reset(T* p)
{
if(p == NULL) reset((ref_counter*)NULL);
else reset(new ref_counter(p));
}
smart_ptr& operator = (const smart_ptr& sp){ reset(sp.refcount); return *this; }
smart_ptr& operator = (T* p){ reset(p); return *this; }
T* operator -> (){ return get(); }
operator T* () const { return get(); }
bool operator ! (){ return get()==NULL; }
bool operator == (const smart_ptr& sp){ return get()==sp.get(); }
bool operator != (const smart_ptr& sp){ return get()!=sp.get(); }
private:
void reset(ref_counter* rc)
{
if(rc != NULL) rc->addRef();
ref_counter* oldref = refcount;
refcount = rc;
if(oldref != NULL) oldref->release();
}
ref_counter* refcount;
};

大家看这样做还行吧?或者有什么更好的方法?
...全文
993 58 打赏 收藏 转发到动态 举报
写回复
用AI写文章
58 条回复
切换为时间正序
请发表友善的回复…
发表回复
LMXEQ5 2010-04-27
  • 打赏
  • 举报
回复
才知道,标准库里面原来也有这个!收藏了
glacier3d 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 37 楼 pengzhixi 的回复:]

引用 36 楼 glacier3d 的回复:
引用 30 楼 selooloo 的回复:

引用 26 楼 glacier3d 的回复:
delete this时,先调用~ref_counter()然后释放内存,以后就不再调用~ref_counter()了,也就不再访问ptr了。不知道我说的是你指的吗?
我感觉destroy后才能触发~ref_counter(),你先调用~ref_co……

你应该还要考虑到传递派生类对象的指针进去。
[/Quote]

这个的确没有考虑,我目前用的环境比较简单,呵呵,多谢提醒!
pengzhixi 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 36 楼 glacier3d 的回复:]
引用 30 楼 selooloo 的回复:

引用 26 楼 glacier3d 的回复:
delete this时,先调用~ref_counter()然后释放内存,以后就不再调用~ref_counter()了,也就不再访问ptr了。不知道我说的是你指的吗?
我感觉destroy后才能触发~ref_counter(),你先调用~ref_counter(),再delete this是怎么实现……
[/Quote]

你应该还要考虑到传递派生类对象的指针进去。
glacier3d 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 selooloo 的回复:]

引用 26 楼 glacier3d 的回复:
delete this时,先调用~ref_counter()然后释放内存,以后就不再调用~ref_counter()了,也就不再访问ptr了。不知道我说的是你指的吗?
我感觉destroy后才能触发~ref_counter(),你先调用~ref_counter(),再delete this是怎么实现的呢
[/Quote]

C++的delete语意如此,可以自己写代码试试
glacier3d 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 julykey 的回复:]

引用 26 楼 glacier3d 的回复:
delete this时,先调用~ref_counter()然后释放内存,以后就不再调用~ref_counter()了,也就不再访问ptr了。不知道我说的是你指的吗?

我觉得这里有点问题。如果是这么构造的
C/C++ code

int* newInt=new int(10);
smart_ptr<int>* sptr=new smart……

那这里析构完newInt,再析构sptr的话就会出问题,因为此时ptr已经析构了。
[/Quote]
ref_counter只是个内部类,使用是有限制的,是不能这样用的
glacier3d 2010-04-26
  • 打赏
  • 举报
回复
谢谢各位的回复!其实我写这个主要是在小环境下用着比较轻便些,在一些复杂环境下当然还得用标准库里的,呵呵
colorfulcode 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 pengzhixi 的回复:]
引用 32 楼 colorfulcode 的回复:
引用 1 楼 jackyjkchen 的回复:
个人总觉得auto_ptr不靠谱,所以干脆不用……

C++不是C#和java,加上这东西总有些不伦不类。


为什么不靠谱??


有一个对象所有权转移的问题。
[/Quote]

那就是说auto_ptr很“自私”;而share_ptr很“大方”,受人爱戴
glacier3d 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 48 楼 fallening 的回复:]

线程问题呢?

每个对象相对于纯粹的指针,浪费多少空间?
[/Quote]

1、太复杂的情况都没考虑,只是写个轻便点的类,在简单环境下简单应用,线程还是留待外部考虑了
2、比4字节的指针多几个字节自然是不可避免的,这个标准库里的智能指针也是不可避免的
glacier3d 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 40 楼 selooloo 的回复:]

C/C++ code

#include <iostream>
using namespace std;

template <class T>
class ref_counter
{
public:
ref_counter(T* p){ count = 0; ptr = p; }
void addRef(){ count++; }
vo……

试了下,destroy会调用一次析构,但不知道是delete this 之前,还是delete this 之后
不过之后还会再调用一次析构,就是调用两次析构函数
[/Quote]
你说的没错,但你写这个和我上面写的是不一样的。

我前面回复都说过了,我那个ref_counter是内部使用的,是有限制的,不能ref_counter<int> rf(p)用,你看我代码里析构函数都放到private下了,这样用编译都不通过
pengzhixi 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 colorfulcode 的回复:]
引用 1 楼 jackyjkchen 的回复:
个人总觉得auto_ptr不靠谱,所以干脆不用……

C++不是C#和java,加上这东西总有些不伦不类。


为什么不靠谱??
[/Quote]

有一个对象所有权转移的问题。
colorfulcode 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 jackyjkchen 的回复:]
个人总觉得auto_ptr不靠谱,所以干脆不用……

C++不是C#和java,加上这东西总有些不伦不类。
[/Quote]

为什么不靠谱??
YT158828 2010-04-26
  • 打赏
  • 举报
回复
学习下
herman~~ 2010-04-26
  • 打赏
  • 举报
回复
觉得auto——ptr不靠谱.可以自己参考google,写一份smartptr
selooloo 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 glacier3d 的回复:]
delete this时,先调用~ref_counter()然后释放内存,以后就不再调用~ref_counter()了,也就不再访问ptr了。不知道我说的是你指的吗?[/Quote]
我感觉destroy后才能触发~ref_counter(),你先调用~ref_counter(),再delete this是怎么实现的呢
kingstarer 2010-04-26
  • 打赏
  • 举报
回复
把vector包装一下 新声明一个类继承自vector 析构时调用delete
linsen_519 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 loaden 的回复:]

引用 18 楼 mstlq 的回复:

所以我倾向于用boost::shared_ptr

哦,boost在实际工程中使用的多么?我没在开发公司,不了解。
shared_ptr铁定是下一个标准,而且已经进入主流编译器的标准库中。
当标准使用又何妨?
[/Quote]
yes~ 铁定将出现在下一个标准里~ 因为shared_ptr太优秀了,用了它好比站在巨人的肩膀上~
dungeonsnd 2010-04-26
  • 打赏
  • 举报
回复
写C++的太善于写复杂性太高的代码,个人觉得复杂性高的同时可能会带来安全性的降低,
COM里设计得那么复杂,不是说对于调用者来说就一点安全性问题都没有的吧。 尽量使用别人设计好的应该更好。
getoneking 2010-04-26
  • 打赏
  • 举报
回复
mark~~
dungeonsnd 2010-04-26
  • 打赏
  • 举报
回复
用标准的boost::shared_ptr都不是绝对安全的,或者说你必须谨慎再谨慎的写代码。
况且你自己写的这个类,如何保证它比标准的安全性高?
fallening 2010-04-26
  • 打赏
  • 举报
回复
线程问题呢?

每个对象相对于纯粹的指针,浪费多少空间?

加载更多回复(37)

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧