灵巧指针(smartpointer)的类型转换

just4free 2006-07-17 04:11:09
#include <iostream.h>
template<class X> class auto_ptr
{
public:
typedef X element_type;
explicit auto_ptr(X* p = 0) throw(): the_p(p) {}
auto_ptr(auto_ptr<X>& a) throw(): the_p(a.release()){}

auto_ptr<X>& operator =(auto_ptr<X>& rhs) throw()
{
reset(rhs.release());
return *this;
}
~auto_ptr() throw() {delete the_p;}
X& operator* () const throw() {return *the_p;}
X* operator-> () const throw() {return the_p;}
X* get () const throw() {return the_p;}
X* release() throw()
{
X* tmp = the_p;
the_p = 0;
return tmp;
}
void reset(X* p = 0) throw()
{
if (the_p!=p)
{
delete the_p;
the_p = p;
}
}
// 模板成员函数为了实现类型转换
template<class Other> operator auto_ptr<Other> () throw( )
{
return ato_ptr<Other>(*this);
}
private:
X* the_p;
};

class A{
public:
A(int i=1):x(i){}
int x;

};
class B: public A
{
public:
B(int j=2):y(j){}
int y;
};

void display(auto_ptr<A>& a)
{
cout<<a->x<<endl;
}

int main( )
{
auto_ptr<A> a(new A());
auto_ptr<B> b(new B());
display(b);//为什么这一步总是出错?????
return 0;
}


...全文
131 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
睡在床板下_ 2006-07-18
  • 打赏
  • 举报
回复
看的头昏
class __ptr_base {
public:
void* _M_p;
void __set(const void* p) { _M_p = __CONST_CAST(void*,p); }
void __set(void* p) { _M_p = p; }
};

template <class _Tp> class auto_ptr_ref {
public:
__ptr_base& _M_r;
_Tp* const _M_p;

auto_ptr_ref(__ptr_base& __r, _Tp* __p) : _M_r(__r), _M_p(__p) { }

_Tp* release() const { _M_r.__set((void*)0); return _M_p; }

};

template<class _Tp> class auto_ptr : public __ptr_base {
public:
typedef _Tp element_type;
typedef auto_ptr<_Tp> _Self;

_Tp* release() {
_Tp* __px = this->get();
this->_M_p = 0;
return __px;
}

void reset(_Tp* __px=0) {
_Tp* __pt = this->get();
if (__px != __pt)
delete __pt;
this->__set(__px);
}

_Tp* get() const { return __REINTERPRET_CAST(_Tp*,__CONST_CAST(void*,_M_p)); }

_Tp* operator->() const {
_STLP_VERBOSE_ASSERT(get()!=0, _StlMsg_AUTO_PTR_NULL)
return get();
}

_Tp& operator*() const {
_STLP_VERBOSE_ASSERT(get()!=0, _StlMsg_AUTO_PTR_NULL)
return *get();
}

auto_ptr() { this->_M_p = 0; }

explicit auto_ptr(_Tp* __px) { this->__set(__px); }


template<class _Tp1> auto_ptr(auto_ptr<_Tp1>& __r) {
_Tp* __conversionCheck = __r.release();
this->__set(__conversionCheck);
}

template<class _Tp1> auto_ptr<_Tp>& operator=(auto_ptr<_Tp1>& __r) {
_Tp* __conversionCheck = __r.release();
reset(__conversionCheck);
return *this;
}


auto_ptr(_Self& __r) { this->__set(__r.release()); }

_Self& operator=(_Self& __r) {
reset(__r.release());
return *this;
}

~auto_ptr() { /* boris : reset(0) might be better */ delete this->get(); }

auto_ptr(auto_ptr_ref<_Tp> __r) {
this->__set(__r.release());
}

_Self& operator=(auto_ptr_ref<_Tp> __r) {
reset(__r.release());
return *this;
}


template<class _Tp1> operator auto_ptr_ref<_Tp1>() {
return auto_ptr_ref<_Tp1>(*this, this->get());
}
template<class _Tp1> operator auto_ptr<_Tp1>() {
return auto_ptr<_Tp1>(release());

operator auto_ptr_ref<_Tp>()
{ return auto_ptr_ref<_Tp>(*this, this->get()); }

};
lddLinan 2006-07-18
  • 打赏
  • 举报
回复
不是编译器的问题,类型转换后返回的是一个临时变量,他是const的,所以foo的参数需要是声明为const
just4free 2006-07-18
  • 打赏
  • 举报
回复
是不是vc6.0编译器有问题?
just4free 2006-07-18
  • 打赏
  • 举报
回复
对我也是从more effective c++上看到的,但是他方法也实现不了
lddLinan 2006-07-18
  • 打赏
  • 举报
回复
上面的实现有问题,使用了强制类型转换,在继承结构稍微复杂的情况下会导致指针错误

《more effective C++》里面是这样实现的

template<class newType> // template function for
operator auto_ptr<newType>() // implicit conversion ops.
{
return auto_ptr<newType>(the_p);//if the type of the_p could no convert to newType, a compile error shows up.
}
但是这样做需要引用计数,否则临时变量析构时会delete the_p.

总之,写一个健全的auto_ptr是很值得研究的
lddLinan 2006-07-18
  • 打赏
  • 举报
回复


template<class T2>
operator auto_ptr<T2>* ()
{
static_cast<T2*>(the_p);
return (auto_ptr<T2>*)this;//bad, which expect that auto_ptr would not be extended
}
just4free 2006-07-18
  • 打赏
  • 举报
回复
谢谢lddLinan,

我是在vc6.0中编译这段代码,但是还是出现类型无法转换的错误。
lddLinan 2006-07-17
  • 打赏
  • 举报
回复
B是A的子类,但是auto_ptr<B>不是auto_ptr<A>的子类

可以在auto_ptr内部定义一个模板函数
template<class T2>
operator auto_ptr<T2>* ()
{
return static_cast<T2*>(the_p);
}

64,637

社区成员

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

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