khi đọc "Beyond the C++ Thư viện Tiêu chuẩn: An Introduction to Boost", tôi có một ví dụ rất thú vị:cách tăng :: shared_ptr hoạt động?
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;;
}
};
và tôi làm một số xét nghiệm:
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
}
những gì tôi cảm thấy rất tò mò đây cách shared_ptr hoạt động như thế nào? cách nó suy ra lớp dẫn xuất B?
Cảm ơn bạn đã giúp đỡ!
cảm ơn tất cả, tôi viết một mẫu đơn giản về cách ~ shared_ptr làm việc
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);
}
chìa khóa là:
- hàm mẫu xây dựng
- tài nguyên không bị xóa trong ~ shared_ptr, nó bị xóa bởi shared_count
Về mặt kỹ thuật, nó thực hiện chuyển đổi từ B * sang A *. Tất cả các truy cập tiếp theo đến con trỏ sẽ sử dụng loại A *. Các hoạt động trên loại B là thông qua tính đa hình tiêu chuẩn (chúng đi qua A *). Ngoại lệ duy nhất là destructor, mà shared_ptr ghi nhớ thông qua cơ chế "deleter" (hoặc một số khái quát hóa). – nobar