Make BReference and BWeakReference behave more like a normal pointer.

* Casts like BReference<Derived> to BReference<Base> are now possible.
* This cast for BWeakReference is, because of the underlying structure, not automatically type safe. I used a simple hack to make the compiler complain if the cast
is not type safe. Please take a look if that can be done better.
* Smaller style and bug fixes.
This commit is contained in:
czeidler 2012-01-05 13:29:47 +13:00
parent dafbb16406
commit 32951c4e63
2 changed files with 82 additions and 10 deletions

View File

@ -41,22 +41,34 @@ template<typename Type = BReferenceable>
class BReference {
public:
BReference()
: fObject(NULL)
:
fObject(NULL)
{
}
BReference(Type* object, bool alreadyHasReference = false)
: fObject(NULL)
:
fObject(NULL)
{
SetTo(object, alreadyHasReference);
}
BReference(const BReference<Type>& other)
: fObject(NULL)
:
fObject(NULL)
{
SetTo(other.fObject);
}
template <typename OtherType>
BReference(const BReference<OtherType>& other)
:
fObject(NULL)
{
SetTo(other.Get());
}
~BReference()
{
Unset();
@ -113,6 +125,19 @@ public:
return *this;
}
BReference& operator=(Type* other)
{
SetTo(other);
return *this;
}
template <typename OtherType>
BReference& operator=(const BReference<OtherType>& other)
{
SetTo(other.Get());
return *this;
}
bool operator==(const BReference<Type>& other) const
{
return (fObject == other.fObject);

View File

@ -87,6 +87,22 @@ public:
SetTo(other);
}
template <typename OtherType>
BWeakReference(const BReference<OtherType>& other)
:
fPointer(NULL)
{
SetTo(other.Get());
}
template <typename OtherType>
BWeakReference(const BWeakReference<OtherType>& other)
:
fPointer(NULL)
{
SetTo(other);
}
~BWeakReference()
{
Unset();
@ -110,6 +126,22 @@ public:
}
}
template <typename OtherType>
void SetTo(const BWeakReference<OtherType>& other)
{
// Just a compiler check if the types are compatible.
OtherType* otherDummy = NULL;
Type* dummy = otherDummy;
dummy = NULL;
Unset();
if (other.Get()) {
fPointer = const_cast<WeakPointer*>(other.Get());
fPointer->AcquireReference();
}
}
void SetTo(const BReference<Type>& other)
{
SetTo(other.Get());
@ -140,18 +172,19 @@ public:
return BReference<Type>(object, true);
}
/*! Do not use this if you do not know what you are doing. The WeakPointer
is for internal use only. */
const WeakPointer* Get() const
{
return fPointer;
}
BWeakReference& operator=(const BWeakReference<Type>& other)
{
if (this == &other)
return *this;
SetTo(other.fPointer);
return *this;
}
BWeakReference& operator=(const Type& other)
{
SetTo(&other);
SetTo(other);
return *this;
}
@ -167,6 +200,20 @@ public:
return *this;
}
template <typename OtherType>
BWeakReference& operator=(const BReference<OtherType>& other)
{
SetTo(other.Get());
return *this;
}
template <typename OtherType>
BWeakReference& operator=(const BWeakReference<OtherType>& other)
{
SetTo(other);
return *this;
}
bool operator==(const BWeakReference<Type>& other) const
{
return fPointer == other.fPointer;