আমি এই প্রশ্নের উত্তর দিতে যাচ্ছি (2 বছর পরে) শেয়ারড_প্টারের খুব সরল বাস্তবায়ন যা ব্যবহারকারী বুঝতে পারবে using
প্রথমত আমি কয়েকটি সাইড ক্লাসে যাচ্ছি, শেয়ারড_পিটার_বেস, এসপি_সক্টেন্ট_বেস এসপি_সকন্টেড_আইপিএল, এবং চেক_ডিলেটার যা শেষটি একটি টেম্পলেট।
class sp_counted_base
{
public:
sp_counted_base() : refCount( 1 )
{
}
virtual ~sp_deleter_base() {};
virtual void destruct() = 0;
void incref(); // increases reference count
void decref(); // decreases refCount atomically and calls destruct if it hits zero
private:
long refCount; // in a real implementation use an atomic int
};
template< typename T > class sp_counted_impl : public sp_counted_base
{
public:
typedef function< void( T* ) > func_type;
void destruct()
{
func(ptr); // or is it (*func)(ptr); ?
delete this; // self-destructs after destroying its pointer
}
template< typename F >
sp_counted_impl( T* t, F f ) :
ptr( t ), func( f )
private:
T* ptr;
func_type func;
};
template< typename T > struct checked_deleter
{
public:
template< typename T > operator()( T* t )
{
size_t z = sizeof( T );
delete t;
}
};
class shared_ptr_base
{
private:
sp_counted_base * counter;
protected:
shared_ptr_base() : counter( 0 ) {}
explicit shared_ptr_base( sp_counter_base * c ) : counter( c ) {}
~shared_ptr_base()
{
if( counter )
counter->decref();
}
shared_ptr_base( shared_ptr_base const& other )
: counter( other.counter )
{
if( counter )
counter->addref();
}
shared_ptr_base& operator=( shared_ptr_base& const other )
{
shared_ptr_base temp( other );
std::swap( counter, temp.counter );
}
// other methods such as reset
};
এখন আমি দুটি "ফ্রি" ফাংশন তৈরি করতে যাচ্ছি যার নাম Make_sp_counted_impl যা নতুন তৈরি হওয়াতে একটি পয়েন্টার ফিরিয়ে দেবে।
template< typename T, typename F >
sp_counted_impl<T> * make_sp_counted_impl( T* ptr, F func )
{
try
{
return new sp_counted_impl( ptr, func );
}
catch( ... ) // in case the new above fails
{
func( ptr ); // we have to clean up the pointer now and rethrow
throw;
}
}
template< typename T >
sp_counted_impl<T> * make_sp_counted_impl( T* ptr )
{
return make_sp_counted_impl( ptr, checked_deleter<T>() );
}
ঠিক আছে, আপনি যখন একটি টেম্প্লেটেড ফাংশনটির মাধ্যমে একটি শেয়ারড_পিটার তৈরি করেন তখন কী হবে তা এই দুটি ফাংশন অপরিহার্য।
template< typename T >
class shared_ptr : public shared_ptr_base
{
public:
template < typename U >
explicit shared_ptr( U * ptr ) :
shared_ptr_base( make_sp_counted_impl( ptr ) )
{
}
// implement the rest of shared_ptr, e.g. operator*, operator->
};
টি বাতিল হয়ে গেলে এবং ইউটি আপনার "পরীক্ষা" শ্রেণীর হলে উপরেরটি কী হবে তা লক্ষ করুন। এটি টি-তে কোনও পয়েন্টার নয়, ইউ-তে একটি পয়েন্টার সহ Make_sp_counted_impl () কল করবে the ধ্বংসটির পরিচালনা এখানে সমস্ত মাধ্যমে সম্পন্ন। ভাগ করা_পিটার_বেস ক্লাসটি অনুলিপি এবং অ্যাসাইনমেন্ট ইত্যাদি সম্পর্কিত রেফারেন্স গণনা পরিচালনা করে The
সুতরাং আপনার শূন্য করতে একটি শেয়ার্ড_পিটার থাকলেও নীচে আপনি যে ধরণের নতুনটিতে পাস করেছেন তার পয়েন্টার পরিচালনা করছেন। নোট করুন যে আপনি যদি ভাগ করে নেওয়ার আগে আপনার পয়েন্টারটিকে একটি অকার্যকর * রূপান্তরিত করে থাকেন, তবে এটি চেক করা_ডিলিটে সংকলন করতে ব্যর্থ হবে যাতে আপনি সেখানেও নিরাপদে থাকেন।