|
Boost Users : |
Subject: Re: [Boost-users] Incomplete types and intrusive_ptr
From: Dominique Devienne (ddevienne_at_[hidden])
Date: 2009-05-12 17:59:22
On Tue, May 12, 2009 at 3:11 PM, Peter Dimov <pdimov_at_[hidden]> 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;
}
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net