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

Class use

DynObj: Wrap a DAO with strict ownership

You need a class that holds a pointer to a dynamically allocated object (i.e. one that was created via new and must be destroyed via delete) and represents the DAO as much as possible where the DAO is used, and enforces strict ownership, i.e.:


The DynObj offers type safety, hence templates are required (inheritence doesn't work because the DAO is only held known by pointer and is not created on the stack but on the heap).

Thus is born the DynObj<T> class.

DynTmp: Return a DAO from a function

With pointers, you would do the following:
Foo* getFoo() {
    Foo* foo = new Foo;
    // do stuff with/to foo, then
    return foo;
This is fraught with error because if the return value from getFoo() is not captured, you get at least a memory (and possibly even a resource) leak.

With DynObj you would want to do, but can't, the following:

DynObj<Foo> getFoo() {
    DynObj<Foo> foo( new Foo );
    // do stuff with/to foo, then
    return foo;
This is not possible because it would require implicit move semantics, which, as seen in the previous usage case, is not supported.

It seems that a special proxy is needed to represent unnamed temporaries like the return value of getFoo(). The role of this proxy should be purely to transfer a DAO from somewhere to a receiving DynObj, in a clear and unmistakable fashion, or if there is no DynObj to recieve it, to delete it. I.e.,

DynTmp<Foo> getFoo() {
    DynObj<Foo> foo( new Foo );
    // do stuff with/to foo, then
    return foo.moveToTmp();

Thus is born the DynTmp<T> class to represent unnamed temporaries. The moveToTmp() is the "clear and unmistakable fashion". DynTmp also allows

    DynTmp<Foo> getFoo() { return new Foo; }
    DynObj<Foo> dynObj = getFoo();
which is safe even if the return value of getFoo() is not used. As explained in the Use of DynObj in value-based containers section, another example of use of DynTmp is
    std::list<DynObj<Foo>::InValueContainer> list;
    list.push_back(DynTmp<Foo>(new Foo));

Note that DynTmp implements move-on-copy semantics.

    DynTmp<T> createT() {return new T;} // return unnamed temp
    DynObj<T> dynObj = createT();

RRef: Automate verification of DAO on access

Ownership of a DAO is often an implementation detail, from the point of view of other functions/class that simply access the DAO (i.e., those that access it don't care who owns it or even if it is owned). Passing around the DAO could easily be done by get a pointer to the DAO from the DynObj. Often, you need to store such pointer for later use. However, verifying that the DAO still exists when it is accessed is not possible without some assistance from the library.

Therefore, provide a class that represents a reference to the DAO, and automatically asserts that the DAO still exists, whenever the DAO is accessed.

Thus is born the RRef<T> class. This class simply stores the pointer to the DAO, given to it by a DynObj, and does an assert before the DAO is accessed through one of RRef's member functions:

    DynObj<Foo> foo;
    foo().method(); // call Foo::method()
    RRef<Foo> refFoo; 
    refFoo().method(); // first assert that foo still exists
                       // THEN call Foo::method()
The method of checking that a DAO exists is an implementation detail and is not discussed here.

RRefable: allow automatic variable to be RRef'd

Conceptually, RRef doesn't care that the pointer it holds is a DAO, just that it has some way of knowing whether that pointer is still pointing to something valid. It is quite plausible that an object created on the stack, i.e. an automatic variable, could have a pointer to it given to another object for later access. For instance, an observer would give a pointer to itself to an observable so the observable can notify the observer when a state change has occurred in the observable.

It would therefore be useful if it would be very simple to make a class usable as an RRef. Even better, if this automatically makes all subclasses also RRef'able. Inheritance is ideal:

    class Bar: public RRefable {...};
    Bar bar; 
    RRef<Bar> refbar(bar);
    refbar().method(); // same as bar.method(), EXCEPT that first
                       // asserts that bar still exists before
                       // calling Bar::method()
The method of checking that a RRefable exists is an implementation detail and is not discussed here.

Next usage pages:

Generated on Mon Aug 4 18:51:32 2003 for NoPtr C++ Library by doxygen 1.3.2