
On Tue, May 12, 2009 at 3:11 PM, Peter Dimov <pdimov@pdimov.com> wrote:
Dominique Devienne:
Is it possible to achieve the ability of shared_ptr<T> to be used as a class member in a class declaration with an incomplete type T, with intrusive_ptr?
The usual approach is to declare:
class X; void intrusive_ptr_add_ref( X* ); void intrusive_ptr_release( X* );
Thanks Peter. This helped me see that I need a declaration of the add_ref/release functions *per* derived class T of RefCountedBase, that I want to fwd declare to avoid including its header. Previously I just declared add_ref/release for RefCountedBase, and since the derivation is not know by just fwd decl SomeRefCounted, I was getting this error: error C2664: 'boost::intrusive_ptr_release' : cannot convert parameter 1 from 'acme::SomeRefCounted *' to 'acme::RefCountedBase *' and wrongly assumed intrusive_ptr<T> required a complete T. I've summarized the issue I was having below. Thanks again for your help. Regards, --DD // in refcountedbase.h namespace acme { class RefCountedBase { public: void ref() { ++refcount_; } void unref() { if (--refcount_ == 0) { cleanup(); delete this; } } static void ref(RefCountedBase* r) { if (r) r->ref(); } static void unref(RefCountedBase* r) { if (r) r->unref(); } protected: RefCountedBase() : refcount_(0) {} RefCountedBase(const RefCountedBase&) : refcount_(0) {} virtual ~RefCountedBase() {} virtual void cleanup() {} private: RefCountedBase& operator=(const RefCountedBase&); private: int refcount_; }; } // in acme/intrusive_ptr.h #include <boost/intrusive_ptr.hpp> namespace acme { using boost::intrusive_ptr; inline void intrusive_ptr_add_ref(acme::RefCountedBase* r) { acme::RefCountedBase::ref(r); } inline void intrusive_ptr_release(acme::RefCountedBase* r) { acme::RefCountedBase::unref(r); } } // in acme/foobar.h // #include <acme/intrusive_ptr.h> namespace acme { class SomeRefCounted; #ifdef DO_FWD_DECL_SOMEREFCOUNTED_HELPERS void intrusive_ptr_add_ref(SomeRefCounted* r); void intrusive_ptr_release(SomeRefCounted* r); #endif class FooBar { intrusive_ptr<SomeRefCounted> some_; // WAS GETTING COMPILE ERROR HERE }; } #ifdef DO_INCLUDE_SOMEREFCOUNTED_H // in acme/somerefcounted.h // lots of #include namespace acme { class SomeRefCounted : public RefCountedBase {}; inline void intrusive_ptr_add_ref(SomeRefCounted* r) { acme::RefCountedBase::ref(r); } inline void intrusive_ptr_release(SomeRefCounted* r) { acme::RefCountedBase::unref(r); } }; #endif void intrusive_ptr(int /*argc*/, const char* /*argv*/[]) { using namespace acme; FooBar foobar; }