在阅读“超越C ++标准库:Boost简介”时,我得到了一个非常有趣的例子:
class A
{
public:
virtual void sing()=0;
protected:
virtual ~A() {};
};
class B : public A
{
public:
virtual void sing( )
{
std::cout << "Do re mi fa so la"<<std::endl;;
}
};
我做了一些测试:
int main()
{
//1
std::auto_ptr<A> a(new B); //will not compile ,error: ‘virtual A::~A()’ is protected
//2
A *pa = new B;
delete pa; //will not compile ,error: ‘virtual A::~A()’ is protected
delete (dynamic_cast<B*>(pa)); //ok
//3
boost::shared_ptr<A> a(new B);//ok
}
我非常好奇的是~share_ptr是如何工作的? 它如何推导派生类B?
感谢您的帮助!
谢谢大家, 我写了一个关于~common_ptr如何工作的简单示例
class sp_counted_base
{
public:
virtual ~sp_counted_base(){}
};
template<typename T>
class sp_counted_base_impl : public sp_counted_base
{
public:
sp_counted_base_impl(T *t):t_(t){}
~sp_counted_base_impl(){delete t_;}
private:
T *t_;
};
class shared_count
{
public:
static int count_;
template<typename T>
shared_count(T *t):
t_(new sp_counted_base_impl<T>(t))
{
count_ ++;
}
void release()
{
--count_;
if(0 == count_) delete t_;
}
~shared_count()
{
release();
}
private:
sp_counted_base *t_;
};
int shared_count::count_(0);
template<typename T>
class myautoptr
{
public:
template<typename Y>
myautoptr(Y* y):sc_(y),t_(y){}
~myautoptr(){ sc_.release();}
private:
shared_count sc_;
T *t_;
};
int main()
{
myautoptr<A> a(new B);
}
关键是:
答案 0 :(得分:11)
令人惊讶的是,这里的关键不是boost::shared_ptr
析构函数,而是它的构造函数。
如果您查看boost/shared_ptr.hpp
,您会发现shared_ptr<T>
并非“只是”让构造函数期待T *
,而是:
template<class Y>
explicit shared_ptr( Y * p );
当您从//3
构建boost::shared_ptr
时,在B *
中,不会转换为A *
,而shared_ptr
内部结构是根据实际情况构建的B
类型。在销毁对象后,删除发生在B
指针上(而不是通过基类指针)。
答案 1 :(得分:3)
shared_ptr
类模板具有类类型shared_count
的成员,而类型成员类型指向类sp_counted_base
的成员。类shared_count
的构造函数模板将指向类模板sp_counted_impl_p
的实例的指针分配给此成员,该构件由构造函数参数的类型而不是shared_ptr::value_type
模板化。 sp_counted_base
有一个纯虚拟成员函数dispose
,它被sp_counted_impl_p
覆盖。因为sp_counted_impl_p
知道示例中的类型B
,所以它可以在不访问基类析构函数的情况下删除它,并且因为它使用虚拟调度,所以在运行时确定类型。此方法需要参数和子类型多态性的组合。