Main Page | Namespace List | Class Hierarchy | Compound List | File List | Namespace Members | Compound Members | File Members | Related Pages

NoPtr::DynObj< ObjType, Context > Class Template Reference

#include <DynObj.hh>

List of all members.


Detailed Description

template<typename ObjType, class Context>
class NoPtr::DynObj< ObjType, Context >

Class DynObj<TT> is a proxy for a Dynamically Allocated Object (DAO -- i.e., an object created via a call to new) of type TT.

Main methods:

Example 1:

class Foo 
{
    Foo(int,int);
    void method();
    void constMethod() const;
};

void f() 
{
    DynObj<Foo> foo(new Foo(1,2));
    foo().method(); // call Foo::method()
    foo.reset(); // destroy the DAO
    assert( foo.isNull() );
} // foo empty so nothing to destroy

Example 2:

void g()
{
    DynObj<const Foo> foo2; // empty
    assert( foo2.isNull() );
    foo2.acquire(new Foo(3,4));
    foo2().constMethod();
} // foo2 DAO is destroyed here

DynObj works in value-based containers such as STL containers (std::list, etc). However, you must specify an extra template parameter when declaring the container: DynObj<TT>::InValueContainer. Populating the container can be done in several ways:

  1. from an already existing object: move it to the container, via DynObj::giveAway();
  2. from temporaries: as with normal objects, give a temporary to the container; in the NoPtr library, this is done via an instance of DynTmp, or a call to the dynTmp helper function, or an instance of DynObj chained with a call to DynObj::giveAway();

All of these are shown in example 3 below.

Example 3:

void g()
{
    typedef List std::list<DynObj<Foo>::InValueContainer>;
    
    List list; 
    // populate from existing object:
    DynObj<Foo> foo(new Foo(9,10));
    list.push_back(foo.giveAway());
    
    // populate using temporaries
    list.push_back(DynTmp<Foo>(new Foo(5,6)));
    list.push_back(dynTmp(new Foo(7,8))); 
    list.push_back(DynObj<Foo>(new Foo(9,10)).giveAway());
    
    // do something to container
    std::sort(list.begin(), list.end());
} // all DAO's in list are destroyed here

Note:
The second template parameter to DynObj is therefore not just anything you want, but must be either NoPtr::InValueContainer, NoPtr::InValueContainerOpt1 or NoPtr::InValueContainerOpt2. You could in principle develop your own Context classes but it is unlikely that they would work without some tweaks to DynObj, so the properties of the Context template parameter are not further described here.

Todo:
Add tests for acquire-same-as-self to make sure works

Definition at line 101 of file DynObj.hh.

Public Types

typedef ObjType ObjectType
 Class of object held, a la auto_ptr.

typedef DynObj< ObjType, NoPtr::InValueContainerInValueContainer
 Type of DynObj to use inside value-based containers (like STL).

typedef DynObj< ObjType, NoPtr::InValueContainerOpt1InValueContainerOpt1
 Slightly optimized version of InValueContainer.

typedef DynObj< ObjType, NoPtr::InValueContainerOpt2InValueContainerOpt2
 Slightly optimized version of InValueContainerOpt1.


Public Member Functions

Construct/Destruct
 DynObj () throw ()
 Create empty proxy.

 DynObj (ObjType *ptr) throw ()
 Create from a pointer. The ptr becomes owned by us.

template<typename ObjType2>  DynObj (std::auto_ptr< ObjType2 > &aptr) throw ()
 Create from a std::auto_ptr. The aptr becomes owned by us.

template<typename ObjType2>  DynObj (const DynTmp< ObjType2 > &mobj) throw ()
 Construct from an unnamed temporary.

 ~DynObj ()
 Destroy the DAO owned. Notify any RRef's linked to us too.

Take ownership of a DAO
void acquire (ObjType *ptr)
 Take ownership of a DAO pointed to by ptr.

template<typename ObjType2> void acquire (std::auto_ptr< ObjType2 > &aptr)
 Take ownership of a DAO contained in aptr.

template<typename ObjType2, class Context2> void acquire (DynObj< ObjType2, Context2 > &rhs)
 Take ownership of the DAO contained in rhs.

template<typename ObjType2> void acquire (const DynTmp< ObjType2 > &mobj)
 Take ownership of the DAO contained in the mobj unnamed temporary.

Other mutators
void reset ()
 Reset to default-constructed state. Destroys DAO if one was owned.

void swap (DynObj &rhs) throw ()
 Swap two dynobj's.

ObjType * release () throw ()
 Release the DAO that we own.

DynTmp< ObjType > moveToTmp () throw ()
 Move the DAO that we own to an unnamed temporary.

DynTmp< ObjType > giveAway () throw ()
 This is the same as a call to release but the DAO that we release is in a DynTmp unnamed temporary.

Other accessors
bool isNull () const throw ()
 If we are not owning a DAO, return true, otherwise return false.

bool isNotNull () const throw ()
 If we are owning a DAO, return true, otherwise return false.

ObjType * getPtr () const throw ()
 Get the pointer that refers to the DAO.

Operators
ObjType & operator() () const
 The operator that gets you a reference to the DAO.

ObjType & operator * () const
 This operator is more convenient than operator() if you want to use ObjType from an iterator.

template<typename ObjType2> void operator= (const DynTmp< ObjType2 > &mobj)
 Same as this->acquire(mobj).

template<typename ObjType2, class Context2> bool operator< (const DynObj< ObjType2, Context2 > &rhs) const throw ()
 Compare for ordering.

template<typename ObjType2, class Context2> bool operator== (const DynObj< ObjType2, Context2 > &rhs) const throw ()
 Compare for equality.

template<typename ObjType2, class Context2> bool operator!= (const DynObj< ObjType2, Context2 > &rhs) const throw ()
 Compare for inequality. Uses !operator==.

 operator const DynObj () const throw ()
 Convert a DynObj<ObjType> to a reference to a const DynObj<const ObjType>.


Member Function Documentation

template<typename ObjType, class Context>
template<typename ObjType2, class Context2>
void NoPtr::DynObj< ObjType, Context >::acquire DynObj< ObjType2, Context2 > &  rhs  )  [inline]
 

Take ownership of the DAO contained in rhs.

The rhs becomes empty. A call to dynobj.acquire(rhs) is equivalent to dynobj = rhs.release() or to dynobj = rhs.giveAway() but is more efficient.

Definition at line 197 of file DynObj.hh.

References NoPtr::DynObj< ObjType, Context >::_obj, NoPtr::DynObj< ObjType, Context >::_rrefUsage, and NoPtr::NullPtr.

template<typename ObjType, class Context>
template<typename ObjType2>
void NoPtr::DynObj< ObjType, Context >::acquire const DynTmp< ObjType2 > &  mobj  )  [inline]
 

Take ownership of the DAO contained in the mobj unnamed temporary.

The mobj hold null thereafter.

Definition at line 214 of file DynObj.hh.

References NoPtr::DynTmp< ObjType >::deliver(), and NoPtr::DynObj< ObjType, Context >::reset().

template<typename ObjType, class Context>
ObjType* NoPtr::DynObj< ObjType, Context >::release  )  throw () [inline]
 

Release the DAO that we own.

If we are null (i.e. not owning anything), returns NULL. The caller is responsible for calling delete on the pointer received.

Definition at line 247 of file DynObj.hh.

References NoPtr::NullPtr.

template<typename ObjType, class Context>
DynTmp<ObjType> NoPtr::DynObj< ObjType, Context >::moveToTmp  )  throw () [inline]
 

Move the DAO that we own to an unnamed temporary.

This makes the move explicit so you don't forget that, after this call, *this is empty.

Definition at line 260 of file DynObj.hh.

References NoPtr::NullPtr.

Referenced by NoPtr::DynObj< ObjType, Context >::giveAway().

template<typename ObjType, class Context>
DynTmp<ObjType> NoPtr::DynObj< ObjType, Context >::giveAway  )  throw () [inline]
 

This is the same as a call to release but the DAO that we release is in a DynTmp unnamed temporary.

This is provided only because it expresses clearly a useful operation, often seen when transfering a dynobj to a container (where moveToTmp() would do the same but doesn't express the right concept).

Definition at line 275 of file DynObj.hh.

References NoPtr::DynObj< ObjType, Context >::moveToTmp().

template<typename ObjType, class Context>
ObjType* NoPtr::DynObj< ObjType, Context >::getPtr  )  const throw () [inline]
 

Get the pointer that refers to the DAO.

Useful if you really need pointer ops, such as to link with legacy libraries. Owner, *this still has ownership of the DAO!

Definition at line 299 of file DynObj.hh.

Referenced by NoPtr::RRef< ObjType >::reset().

template<typename ObjType, class Context>
ObjType& NoPtr::DynObj< ObjType, Context >::operator()  )  const [inline]
 

The operator that gets you a reference to the DAO.

This is the closest that C++ gets us to true proxy syntax. I.e., given a DynObj<Foo> dynobj, you do dynobj().method() to access Foo::method of the DAO. True proxy syntax would require us to overload operator. instead of operator(), this is not yet allowed in C++.

Definition at line 317 of file DynObj.hh.

template<typename ObjType, class Context>
ObjType& NoPtr::DynObj< ObjType, Context >::operator *  )  const [inline]
 

This operator is more convenient than operator() if you want to use ObjType from an iterator.

For instance,

                typedef DynObj<Foo>::InValueContainer DynFoo;
                std::list<DynFoo>::iterator ii = list.begin();
                ii->reset(); // calls DynObj<Foo>::reset();
                (**ii).method(); // calls Foo::method();
                (*ii)().method(); // same but rather hard to read
Note that, like operator(), it must only be called when this->isNull() returns false.

Definition at line 334 of file DynObj.hh.

template<typename ObjType, class Context>
template<typename ObjType2, class Context2>
bool NoPtr::DynObj< ObjType, Context >::operator< const DynObj< ObjType2, Context2 > &  rhs  )  const throw () [inline]
 

Compare for ordering.

This compares the DAO's, i.e. an operator<(ObjType,ObjType2) must be available. If both DAO's are null, this method returns true. If only one is null, it considers the null value to be smaller than any other pointer. This means that when sorting a container, all nulls will end up at the beginning of the container.

This behavior was chosen because operator< is likely to be used only for STL algorithms on containers, where nullness is possible and throwing or asserting are inadequate. Outside of this case, comparing two DynObj should be done by dynObj1() < dynObj2() since this will do the error checking that operator() provides.

Todo:
Test this, especially sorting with nulls

Definition at line 362 of file DynObj.hh.

References NoPtr::NullPtr.

template<typename ObjType, class Context>
template<typename ObjType2, class Context2>
bool NoPtr::DynObj< ObjType, Context >::operator== const DynObj< ObjType2, Context2 > &  rhs  )  const throw () [inline]
 

Compare for equality.

Equal if DAO == rhs.DAO, or if both are null. Unequal otherwise.

Definition at line 377 of file DynObj.hh.

template<typename ObjType, class Context>
NoPtr::DynObj< ObjType, Context >::operator const DynObj  )  const throw () [inline]
 

Convert a DynObj<ObjType> to a reference to a const DynObj<const ObjType>.

This is the conversion operator that allows you to pass a DynObj<TT> to a function expecting a const DynObj<const TT>& without creating a temporary. Naturally, const correctness disallows the reverse operation and requires that the return reference be const.

Definition at line 413 of file DynObj.hh.

References NoPtr::DynObj< ObjType, Context >::_obj, and NoPtr::DynObj< ObjType, Context >::_rrefUsage.


The documentation for this class was generated from the following file:
Generated on Mon Aug 4 18:51:33 2003 for NoPtr C++ Library by doxygen 1.3.2