एक कस्टम deleter का उपयोग करें
समस्या यह है कि unique_ptr<T>
विध्वंसक T::~T()
को अपने स्वयं के विध्वंसक को, उसके चालन कार्य संचालक को, और unique_ptr::reset()
सदस्य कार्य (केवल) को कॉल करना होगा । हालाँकि, इन्हें कई PIMPL स्थितियों (पहले से ही बाहरी वर्ग के विध्वंसक और चाल असाइनमेंट ऑपरेटर) में कहा जाना चाहिए (स्पष्ट या स्पष्ट रूप से)।
जैसा कि पहले ही एक और जवाब में बताया, एक ही रास्ता है कि से बचने के लिए ले जाने के लिए है सभी कार्य है कि आवश्यकता होती है unique_ptr::~unique_ptr()
, unique_ptr::operator=(unique_ptr&&)
और unique_ptr::reset()
स्रोत फ़ाइल जहां pimpl सहायक वर्ग वास्तव में परिभाषित किया गया है में।
हालांकि, यह असुविधाजनक है और कुछ हद तक पिंपल इडोइम के बिंदु को परिभाषित करता है। एक बहुत क्लीनर समाधान जो एक कस्टम डिलेटर का उपयोग करने से बचता है और केवल अपनी परिभाषा को स्रोत फ़ाइल में स्थानांतरित करता है जहां दाना सहायक वर्ग रहता है। ये रहा एक सरल उदाहरण:
// file.h
class foo
{
struct pimpl;
struct pimpl_deleter { void operator()(pimpl*) const; };
std::unique_ptr<pimpl,pimpl_deleter> m_pimpl;
public:
foo(some data);
foo(foo&&) = default; // no need to define this in file.cc
foo&operator=(foo&&) = default; // no need to define this in file.cc
//foo::~foo() auto-generated: no need to define this in file.cc
};
// file.cc
struct foo::pimpl
{
// lots of complicated code
};
void foo::pimpl_deleter::operator()(foo::pimpl*ptr) const { delete ptr; }
एक अलग डिलेटर वर्ग के बजाय, आप एक फ्री फ़ंक्शन या लैंबडा के साथ संयोजन के static
सदस्य का उपयोग कर सकते हैं foo
:
class foo {
struct pimpl;
static void delete_pimpl(pimpl*);
std::unique_ptr<pimpl,[](pimpl*ptr){delete_pimpl(ptr);}> m_pimpl;
};