Utils::AbstractValue< AbstractType, NullObjectType, HierarchyRoot > Class Template Reference

#include <AbstractValue.h> [code]

Inheritance diagram for Utils::AbstractValue< AbstractType, NullObjectType, HierarchyRoot >:

Inheritance graph
[legend]
List of all members.

Detailed Description

template<typename AbstractType, typename NullObjectType, typename HierarchyRoot = AbstractType>
class Utils::AbstractValue< AbstractType, NullObjectType, HierarchyRoot >

A generic Value Object wrapper for abstract data types.

Requirements for the template parameter AbstractType:

Template parameters:

AbstractValue can be specialized with any abstract data type that fulfills the above requirements. With its help, data objects, for which only the abstract base is known, can be treated as Value Objects - they can be copied and compared as if their concrete type was known. Thus, passing or returning values of unknow dynamic type is possible:

    class DataBase {}; // Abstract class.
    class NullData : public DataBase {}; // Null Data Object.
    class ConcreteDataA : public DataBase {}; // Concrete Data implementation.
    class ConcreteDataB : public DataBase {}; // Concrete Data implementation.
    ...
    typedef AbstractValue <DataBase, NullData> Data;
    ...
    Data makeDataFromRawBytes (const QByteArray &bytes)
    {
        if (...)
            return Data (ConcreteDataA());
        else
            return Data (ConcreteDataB());
    }

Complex data hierarchies containing multiple leve of abstraction (and AbstractType classes) can also be modelled:

    class DataBase {}; // Abstract class (hierarchy root).
    class NullData : DataBase {}; // Null Data Object.
    class PacketBase : public DataBase {}; // Abstract class.
    class NullPacket : public PacketBase {}; // Null Packet Object.
    class ConcretePacket : public PacketBase {}; // Concrete Packet impelementation.
    ...
    typedef AbstractValue <DataBase, NullData> Data;
    typedef AbstractValue <PacketBase, NullPacket, DataBase> Packet;
    ...
    void main()
    {
        Data data;                  // Creates a default Data object that
                                    // encapsulates a NullData object.

        Packet packet;              // Creates a default Packet object that
                                    // encapsulates a NullPacket object.

        packet = ConcretePacket()); // Assigns the new ConcretePacket object to
                                    // packet, which will release the NullPacket
                                    // object and will encapsulate a copy of the
                                    // new ConcretePacket object.

        data = packet;              // Assigning Packet to Data works!
                                    // Both packet and data encapsulate copies
                                    // of the ConcretePacket object.

        packet = data;              // This assignment would work too!
                                    // If data encapsulates an object that
                                    // derives from DataBase but not from
                                    // PacketBase an std::bad_cast exception
                                    // will be thrown at runtime. If the types
                                    // match, the assignment will be done.
    }

Note:
The encapsulated object is copied in each of the ctors in the assignment operator and in the cast operators. To make copying faster, implicit sharing of private data could be implemented in your data hierarchy.

The template parameter HierarchyRoot is needed because the virtual copy ctor returns a auto_ptr instead of a raw pointer. If Base::copy() returned a Base *, then Derived::copy() could return a Derived * and all would have been fine. But because copy() returns an auto_ptr <Base>, we are not allowed to return auto_ptr <Derived> in the derived class.

Todo:
http://carcino.gen.nz/tech/cpp/multiple_inheritance_this.php The safest way would be to use dynamic_cast in operator* and operator-> even though static_cast is faster and will work in most of the cases. Should we switch to dynamic_cast?

Definition at line 126 of file AbstractValue.h.

Public Member Functions

 AbstractValue ()
 Create a Null AbstractValue object.
 AbstractValue (const AbstractType &object)
 Create an AbstractValue object encapsulating a copy of object.
 AbstractValue (const AbstractValue &other)
 AbstractValue copy ctor.
AbstractValueoperator= (const AbstractValue &other)
 Assignment operator.
bool operator== (const AbstractValue &other) const
 Compares the objects encapsulated by two AbstractValue objects.
bool operator!= (const AbstractValue &other) const
 Compares the objects encapsulated by two AbstractValue objects.
AbstractType & operator * ()
 Indirection operator - returns a reference to the encapsulated object.
const AbstractType & operator * () const
 Indirection operator - returns a reference to the encapsulated object.
AbstractType * operator-> ()
 Arrow operator - returns a pointer to the encapsulated object.
const AbstractType * operator-> () const
 Arrow operator - returns a pointer to the encapsulated object.
template<typename RelatedAbstractType, typename RelatedNullType>
 operator AbstractValue () const
 Cast operator (casts to other AbstractValue instantiations).

Private Attributes

auto_ptr< HierarchyRoot > object_
 An auto_ptr to the encapsulated object.


Constructor & Destructor Documentation

template<typename AbstractType, typename NullObjectType, typename HierarchyRoot = AbstractType>
Utils::AbstractValue< AbstractType, NullObjectType, HierarchyRoot >::AbstractValue  )  [inline]
 

Create a Null AbstractValue object.

The new object will encapsulate a NullObjectType object.

Definition at line 133 of file AbstractValue.h.

template<typename AbstractType, typename NullObjectType, typename HierarchyRoot = AbstractType>
Utils::AbstractValue< AbstractType, NullObjectType, HierarchyRoot >::AbstractValue const AbstractType &  object  )  [inline]
 

Create an AbstractValue object encapsulating a copy of object.

Parameters:
object is an object a copy of which will be enapsulate by this.

Definition at line 142 of file AbstractValue.h.

template<typename AbstractType, typename NullObjectType, typename HierarchyRoot = AbstractType>
Utils::AbstractValue< AbstractType, NullObjectType, HierarchyRoot >::AbstractValue const AbstractValue< AbstractType, NullObjectType, HierarchyRoot > &  other  )  [inline]
 

AbstractValue copy ctor.

Parameters:
other is the AbstractValue object whose encapsulated object should be copied and the copy encapsulated by this.

Definition at line 151 of file AbstractValue.h.


Member Function Documentation

template<typename AbstractType, typename NullObjectType, typename HierarchyRoot = AbstractType>
const AbstractType& Utils::AbstractValue< AbstractType, NullObjectType, HierarchyRoot >::operator *  )  const [inline]
 

Indirection operator - returns a reference to the encapsulated object.

Definition at line 206 of file AbstractValue.h.

template<typename AbstractType, typename NullObjectType, typename HierarchyRoot = AbstractType>
AbstractType& Utils::AbstractValue< AbstractType, NullObjectType, HierarchyRoot >::operator *  )  [inline]
 

Indirection operator - returns a reference to the encapsulated object.

Definition at line 199 of file AbstractValue.h.

template<typename AbstractType, typename NullObjectType, typename HierarchyRoot = AbstractType>
template<typename RelatedAbstractType, typename RelatedNullType>
Utils::AbstractValue< AbstractType, NullObjectType, HierarchyRoot >::operator AbstractValue  )  const [inline]
 

Cast operator (casts to other AbstractValue instantiations).

Code using this cast operator will always compile as long as AbstractType and RelatedAbstractType are in a is-a relationship. A compiler error will be produced otherwise.

"Up-casts" from AbstractValue <DerivedType, ...> to AbstractValue <BaseType, ...> will always work. "Down-casts" from AbstractValue <BaseType, ...> to AbstractValue <DerivedType, ...> will throw an std::bad_cast exception at runtime if the convertion is invalid.

Note:
The implementation of this function uses dynamic_cast to do both the real up-casing/down-casting of the pointers to the encapsulated objects.

Definition at line 245 of file AbstractValue.h.

template<typename AbstractType, typename NullObjectType, typename HierarchyRoot = AbstractType>
bool Utils::AbstractValue< AbstractType, NullObjectType, HierarchyRoot >::operator!= const AbstractValue< AbstractType, NullObjectType, HierarchyRoot > &  other  )  const [inline]
 

Compares the objects encapsulated by two AbstractValue objects.

Parameters:
other is the object whose encapsulated object has to be compared with the encapsulated object in this.
Returns:
false if both encapsualted objects have the different values (their isEqualTo() returned true).

true otherwise.

Definition at line 193 of file AbstractValue.h.

template<typename AbstractType, typename NullObjectType, typename HierarchyRoot = AbstractType>
const AbstractType* Utils::AbstractValue< AbstractType, NullObjectType, HierarchyRoot >::operator->  )  const [inline]
 

Arrow operator - returns a pointer to the encapsulated object.

Definition at line 220 of file AbstractValue.h.

template<typename AbstractType, typename NullObjectType, typename HierarchyRoot = AbstractType>
AbstractType* Utils::AbstractValue< AbstractType, NullObjectType, HierarchyRoot >::operator->  )  [inline]
 

Arrow operator - returns a pointer to the encapsulated object.

Definition at line 213 of file AbstractValue.h.

template<typename AbstractType, typename NullObjectType, typename HierarchyRoot = AbstractType>
AbstractValue& Utils::AbstractValue< AbstractType, NullObjectType, HierarchyRoot >::operator= const AbstractValue< AbstractType, NullObjectType, HierarchyRoot > &  other  )  [inline]
 

Assignment operator.

Parameters:
other is the AbstractValue object whose encapsulated object should be copied and the copy encapsulate by this. The old encapsulated object will be deleted.
Returns:
A reference to this.

Definition at line 163 of file AbstractValue.h.

template<typename AbstractType, typename NullObjectType, typename HierarchyRoot = AbstractType>
bool Utils::AbstractValue< AbstractType, NullObjectType, HierarchyRoot >::operator== const AbstractValue< AbstractType, NullObjectType, HierarchyRoot > &  other  )  const [inline]
 

Compares the objects encapsulated by two AbstractValue objects.

Parameters:
other is the object whose encapsulated object has to be compared with the encapsulated object in this.
Returns:
true if both encapsualted objects have the same value (their isEqualTo() returned true).

false otherwise.

Definition at line 178 of file AbstractValue.h.


Member Data Documentation

template<typename AbstractType, typename NullObjectType, typename HierarchyRoot = AbstractType>
auto_ptr<HierarchyRoot> Utils::AbstractValue< AbstractType, NullObjectType, HierarchyRoot >::object_ [private]
 

An auto_ptr to the encapsulated object.

Definition at line 257 of file AbstractValue.h.


The documentation for this class was generated from the following file: