新年快乐,另请教个push_back指针的小问题

mm11214014 2012-01-24 03:01:59
自己写了个小智能指针,这样往容器里放指针时就不用担心析构的问题了。可是往vector里放智能指针后,总会出现很诡异的问题,代码如下:
智能指针:

template<typename T>
class _shared_ptr
{
public:
_shared_ptr(T *ptr) : _ptr(ptr), _cnt(new long(1)){}

template<typename U>
_shared_ptr(_shared_ptr<U> &other)
{
_ptr = reinterpret_cast<T*>(other.operator->());
_cnt = other.get_cnt();
++*_cnt;
}

template<typename U>
_shared_ptr<T>& operator=(const _shared_ptr<U> &rhs)
{
if (this != &other)
{
if (!--*_cnt)
{
delete _ptr;
delete _cnt;
}
_ptr = reinterpret_cast<T*>(other.operator->());
_cnt = other.get_cnt();
++*_cnt;
}
return *this;
}

~_shared_ptr()
{
if (!--*_cnt)
{
delete _ptr;
delete _cnt;
}
}

T* operator->() const
{
assert(_ptr);
return _ptr;
}

T& operator*() const
{
assert(_ptr);
return *_ptr;
}

long* get_cnt() const
{
return _cnt;
}
private:
T *_ptr;
long *_cnt;
};


测试部分:

int _tmain(int argc, _TCHAR* argv[])
{
vector<_shared_ptr<int> > vec;
_shared_ptr<int> p1(new int(1));
_shared_ptr<int> p2(new int(2));
vec.push_back(p1);
vec.push_back(p2);
ofstream os("g:\\ptr.txt");
os << vec[0].operator->() << ' ' << *vec[0] << endl;
os << vec[1].operator->() << ' ' << *vec[1] << endl;

return 0;
}


结果是:
00527800 5379384
00527860 2
貌似第一个指针自己析构了,但我实在找不出问题,哪位知道的请不吝赐教,万分感谢!

...全文
239 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
mm11214014 2012-01-25
  • 打赏
  • 举报
回复
谢谢,问题就是你说的,终于解决了。新年快乐。[Quote=引用 11 楼 jim_king_2000 的回复:]

因为下面这个模板函数并不是拷贝构造。
template<typename U>
_shared_ptr(const _shared_ptr<U> &other)
该函数仅当U与T不同的时候,才会被实例化且被调用。仅仅实现上面的函数,那么就相当于没有给出拷贝构造。那么编译器会自动生成一个拷贝构造,实现按位拷贝。这样的语义显然不是楼主需要的。

正确的做法是,模板函数和拷贝构造同时……
[/Quote]
mm11214014 2012-01-25
  • 打赏
  • 举报
回复
嘿嘿,谢谢,高人就在你楼下你呢。[Quote=引用 10 楼 dourgulf 的回复:]

问题可能是出现在第二个模板参数哪里
template<typename U>
_shared_ptr(const _shared_ptr<U> &other)

如果改成是:
_shared_ptr(const _shared_ptr<T> &other)
就行为正常了~

具体为什么还不是很了解,模板这块确实是太少用了,等高手解析。。。

BTW:L……
[/Quote]
mm11214014 2012-01-25
  • 打赏
  • 举报
回复
VS2010啊,我也纳闷,难道是主函数没调用赋值函数,就给忽略了[Quote=引用 6 楼 mm11214014 的回复:]

晕,编译器竟然没报错。多谢提醒。引用 3 楼 qq120848369 的回复:
不知道为什么。。

template<typename U>
_shared_ptr<T>&amp; operator=(const _shared_ptr<U> &amp;rhs)
{
if (this != &amp;other)
{
if (!--*_cnt)
{
d……
[/Quote]
taodm 2012-01-25
  • 打赏
  • 举报
回复
楼主何苦自己造轮子。
boost里ptr_container,现成的;smart_ptr也是现成的。
Jim_King_2000 2012-01-25
  • 打赏
  • 举报
回复
因为下面这个模板函数并不是拷贝构造。
template<typename U>
_shared_ptr(const _shared_ptr<U> &other)
该函数仅当U与T不同的时候,才会被实例化且被调用。仅仅实现上面的函数,那么就相当于没有给出拷贝构造。那么编译器会自动生成一个拷贝构造,实现按位拷贝。这样的语义显然不是楼主需要的。

正确的做法是,模板函数和拷贝构造同时提供。
template<typename U>
_shared_ptr(const _shared_ptr<U> &other);
_shared_ptr(const _shared_ptr<T> &other);
子达如何 2012-01-25
  • 打赏
  • 举报
回复
问题可能是出现在第二个模板参数哪里
template<typename U>
_shared_ptr(const _shared_ptr<U> &other)

如果改成是:
_shared_ptr(const _shared_ptr<T> &other)
就行为正常了~

具体为什么还不是很了解,模板这块确实是太少用了,等高手解析。。。

BTW:LZ的拷贝构造函数的参数少了const修饰。
qq120848369 2012-01-25
  • 打赏
  • 举报
回复
不知道为什么。。

template<typename U>
_shared_ptr<T>& operator=(const _shared_ptr<U> &rhs)
{
if (this != &other)
{
if (!--*_cnt)
{
delete _ptr;
delete _cnt;
}
_ptr = reinterpret_cast<T*>(other.operator->());
_cnt = other.get_cnt();
++*_cnt;
}
return *this;
}

没有other,是rhs
RLib 2012-01-25
  • 打赏
  • 举报
回复
你在析构函数里下断,看断了几次。
go_Michael 2012-01-25
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 mm11214014 的回复:]
谢谢你的解答,貌似这块儿挺纠结

引用 1 楼 go_michael 的回复:
lz 可能是模板类的拷贝构造函数和赋值运算符吧,push_back的时候没有调用到copy construct
[/Quote]

我运行的时候发现确实没有调用到copy 或者 operator =
程序员小迷 2012-01-25
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 mm11214014 的回复:]
晕,编译器竟然没报错。多谢提醒。

引用 3 楼 qq120848369 的回复:
不知道为什么。。

template<typename U>
_shared_ptr<T>&amp; operator=(const _shared_ptr<U> &amp;rhs)
{
if (this != &amp;other)
{
if (!--*_cnt)
{……
[/Quote]

你用的什么编译器,这么神奇?
mm11214014 2012-01-25
  • 打赏
  • 举报
回复
晕,编译器竟然没报错。多谢提醒。[Quote=引用 3 楼 qq120848369 的回复:]
不知道为什么。。

template<typename U>
_shared_ptr<T>& operator=(const _shared_ptr<U> &rhs)
{
if (this != &other)
{
if (!--*_cnt)
{
delete _ptr;
delete _cnt;
}
_p……
[/Quote]
mm11214014 2012-01-25
  • 打赏
  • 举报
回复
谢谢。我也感觉问题似乎在析构这块儿,可是没处下手啊[Quote=引用 2 楼 rrrfff 的回复:]
你要阻止析构
[/Quote]
mm11214014 2012-01-25
  • 打赏
  • 举报
回复
谢谢你的解答,貌似这块儿挺纠结[Quote=引用 1 楼 go_michael 的回复:]
lz 可能是模板类的拷贝构造函数和赋值运算符吧,push_back的时候没有调用到copy construct
[/Quote]
RLib 2012-01-24
  • 打赏
  • 举报
回复
你要阻止析构
go_Michael 2012-01-24
  • 打赏
  • 举报
回复
lz 可能是模板类的拷贝构造函数和赋值运算符吧,push_back的时候没有调用到copy construct

64,644

社区成员

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

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