özel bir silici kullan
Sorun, unique_ptr<T>
yıkıcıyı T::~T()
kendi yıkıcısında, taşıma atama işlecinde ve unique_ptr::reset()
üye işlevinde (yalnızca) çağırması gerektiğidir . Ancak, bunlar birkaç PIMPL durumunda (örtük olarak veya açıkça) çağrılmalıdır (zaten dış sınıfın yıkıcı ve taşıma atama işlecinde).
Zaten başka cevap belirttiği gibi, bu kaçınmanın tek yol taşımaktır tüm gerektiren işlemleri unique_ptr::~unique_ptr()
, unique_ptr::operator=(unique_ptr&&)
veunique_ptr::reset()
Pimpl yardımcı sınıfı aslında tanımlanır kaynak dosyası içine.
Bununla birlikte, bu oldukça elverişsizdir ve pimpl idoim'in noktasını bir dereceye kadar reddeder. Bir kullanmaktır tüm önler Daha net bir çözüm özel deleter ve sadece kaynak dosyadan sivilce yardımcı sınıfı hayatlarını içine tanımını taşıyın. İşte basit bir örnek:
// 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; }
Ayrı bir silme sınıfı yerine, bir lambda ile birlikte ücretsiz bir işlev veya static
üyesi de kullanabilirsiniz foo
:
class foo {
struct pimpl;
static void delete_pimpl(pimpl*);
std::unique_ptr<pimpl,[](pimpl*ptr){delete_pimpl(ptr);}> m_pimpl;
};