Mark Pearl

Any ramblings and blog posts associated with the UNISA COS 2144 tag should be considered study notes for my lectures…

Section Outline Generics and Templates Containers Managed Containers, Composites, and Aggregates Implicitly Shared Classes Generics, Algorithms, and Operators Serializer Pattern Sorted Map Example Questions for this Section Explain the important difference between a template parameter and a function parameter. What does it mean to instantiate a template function? Describe one way to do this. Normally, you need to place template definitions in header files. Why is this? Qt’s container classes are used to collect value types. What kinds of things are not appropriate to store by value in a value collection? Which containers provide mappings from key to value? List and describe at least two, and tell how they are different from each other. What does it mean for a container to “manage” its heap objects? How does a container of pointers to heap objects become a managed container? Generics and Templates C++ supports 4 distinct categories of types…

Primitives (int, char, float, etc) Pointers Instances of class/struct Arrays There is no common base type for these 4 type categories, so we make use of templates to allow for generic functions.

Templates are distinguished by the use of the keyword template, and a template parameter enclosed in angle brackets <>

i.e.

template class String { … } ;

template <class T, int max> Buffer { … T v[max]; };

example of use

String s1;

Buffer <int, 10> intBuf10

Function Templates Function templates are used to create type-checked functions which all work on the same pattern.

When the function is called, different function bodies will be automatically generated by the compiler based on the argument types supplied in the function call.

Each time the compiler see a template function used for the first time with a specific combination of parameter types, it is called template instantiation.

Class Templates Like functions, classes can also use parameterized types. Class templates are used to generate generic containers of data.

Containers Qt container classes are used to collect value types, including pointers to object types (but not objects themselves / shallow copy).

Qt containers are defined as template classes which leave the collected type unspecified. Each data structure is optimized for different kinds of operations.

In Qt there are several template container classes to choose from…

QList QStringList QLinkedList QVector QStack QMap<Key, T> QHash<Key, T> QMultiMap<Key,T> QCache<Key,T> QSet A type parameter T for a template container class or key type for an associative container must be assignable data type. This means that it must have a public default constructor, copy constructor, and assignment operator.

Types derivable from QObject are not assignable.

Managed Containers, Composites, and Aggregates Value containers are containers of uniform (same typed) values. Pointer containers are containers of pointers to (polymorphic commonly typed) objects. They can be managed or unmanaged.

Both kinds of containers can grow at runtime by allocating additional heap memory as needed. This is always done in an exception-safe way.

In the case of pointer containers to heap objects, one must decide which class is responsible for managing the heap objects. UML diagrams can distinguish between managed and unmanaged containers by using composite (filled diamond) and aggregate (empty diamond) connectors.

In general, a managed container is a composite, because the container manages its pointed-to objects, or when a composite is destroyed, it destroys its entire self (including the smaller associated objects).

When one objects embeds another as a sub-object, it is considered a composition.

Typically a managed container deletes any heap objects it owns when the container itself is destroyed. With a Qt container of pointer, one can use qDeleteAll(container), an algorithm that calls delete on each element in the container.

Copying a managed container can be defined in a number of ways…

The feature might be disabled. It might be called a deep copy, where all contained objects are cloned and placed in the new container. It might be a shallow copy, where it copies the references to the contained objects but not the actual objects When a container only provides an indexing or reference navigation mechanism to its objects we call it an aggregate container.

An aggregate container does not manage its objects, it only provides a convenient way to access them. When an aggregate container is deleted, only the references are removed. There is no impact on the underlying objects in the container.

Implicitly Shared Classes A hybrid kind of managed container is implicitly shared container. Container classes in the Qt library implement “lazy copy on write” or implicit sharing. This means they have reasonably fast copy constructors and assignment operators. Only when the copy is actually modified are the collected objects cloned from the original container. That is when there will be a time/memory penalty.

QString and QStringList are both implemented this way, meaning that it is fast to pass and return these objects by value. If you need to change values stored in the container from inside a function, you can pass the container by reference.

Implicitly shared classes work by reference-counting, to prevent the accidental deletion of shared managed objects. Since implicitly shared memory is encapsulated, the user of the class does not need to be concerned with reference counts or direct memory pointers.

Generics, Algorithms, and Operators Overloading operator symbols makes it possible to define a common interface for our classes that is consistent with that of basic types. Many generic algorithms take advantage of this by using the common operators to perform basic functions such as comparison.

Serializer Pattern A serializer is an object that is responsible only for reading or writing objects, With QDataStream, it is already possible to serialize and deserialize all QVariant-supported types, including QList, QMap, QVector, and others.

For other file formats, or more complex object models, we isolate the reading/writing in separate reader and writer classes.

A serializer that reads and writes to files should handle all of the file and/or stream initialization and cleanup. A serializer could also be used to send objects over a network from one socket to another.

Benefits of the Serializer By using the serializer, it is much easier to change the file format, or the transport layer, with only small changes in client code. In addition, removing serialization code from the model makes the model simpler and easier to maintain.



blog comments powered by Disqus

Want to get my personal insights on what I learn as I learn it? Subscribe now!


/