Chapter 7.  Libraries and Design Patterns

Table of Contents

7.1. Building and Reusing Libraries
7.1.1. Organizing Libraries: Dependency Management
7.1.2. Installing Libraries
7.2. Exercise: Installing Libraries
7.3. Frameworks and Components
7.4. Design Patterns
7.4.1. Serializer Pattern: QTextStream and QDataStream
7.4.2. AntiPatterns
7.4.2.1. Points of Departure
7.5. Review Questions

[ fromfile: libraries.xml id: libraries ]

Abstract

Libraries are groups of code modules, organized in a reusable way. This chapter discusses how they are built, reused, and designed. Design Patterns are also introduced and discussed.

The term platform refers to a particular combination of hardware architecture, especially central processing unit (CPU),[52] and software framework, especially operating system (OS).[53] Each computer system can only execute code written in its own low level, platform specific language. This low level machine language does not resemble any natural human language, and few programmers are comfortable working directly with it.

For optimal use of programming resources (especially programmer time) you write programs in a high level language (e.g., C++) so that you can express and share your ideas and precise instructions in a form reasonably close to your own natural language (e.g., English). The task of translating each item in the high level code into machine language, so that it can be executed on a particular computer platform, is handled by a compiler.[54]

Widespread acknowledgment of the value of code reuse has steadily increased the demand for (and production of) code libraries that store useful, reusable, already compiled code so that programmers can exploit its functionality without having to handle any of its source code. A library module is reused when you #include its header file, which specifies its Application Programming Interface (API), in the appropriate source code module. You have already reused several of these from the Standard Library (e.g.,iostream and string) and from Qt (e.g., QString, QTextStream, and QList) . When you reuse an item from a library, it is the job of a linker, during the build process, to establish appropriate connections between the item references in your compiled code and the item definitions in the compiled library code. The resulting executable must find and dynamically link to the compiled libraries (called runtime libraries) at runtime. The compiled library code does not need to be incorporated into the executable file because it can be dynamically linked at runtime. This results in smaller executable files and more efficient use of memory.

A lib is a file that contains one or more compiled files (called object files) indexed to make it easy for the linker to locate symbols (e.g., names of classes, class members, functions, variables, etc.) and their definitions. Collecting several object files in a single lib expedites the linking process significantly.

C++ Libraries can be packaged in a few different ways.

An open source package is usually distributed as a compressed archive containing all source code and header files plus build scripts and documentation. A dev package, sometimes referred to as a "-devel" package by Linux package managers, is usually distributed as an archive containing a lib plus its associated header files. This format enables you to distribute a library without its source code. Others can still compile their applications with it. A runtime library consists of a lib file, without its associated headers, so it can only be used to execute an application that has already been built with the library.

Code Containers

To summarize, the variety of ways that C++ code can be organized and packaged facilitates code sharing and reuse.

Table 7.1 defines some terms that describe containers of code.

Table 7.1. Reusable Components

TermVisible AttributesDescription
class class Classname { body } ; A collection of functions and data members, and descriptions of its lifecycle management (constructors and destructors)
namespace namespace nname { body } ; A collection of declarations and definitions, of classes, functions and static members, perhaps spanning multiple files
header file.hClass definitions, template definitions, function declarations (with default argument definitions), inline definitions, static object declarations
source code module.cppFunction definitions, static object definitions
compiled "object" module.o or .obj Each .cpp module is compiled into a binary module as an intermediate step in building a library or executable.
library.lib or .la (+ .so or .dll if dynamic) An indexed collection of object files linked together. No main() function must exist in any code module in a library.
devel packagelib + header files A library along with accompanying header files
application .exe on windows, no particular extension on *nixA collection of object files, linked with libraries, to form an application. Contains exactly one function definition called main().



[52] e.g., Intel Core 2 Duo or SPARC64 "Venus"

[53] e.g., Linux, Windows7, Mac_OS_X

[54] The Java compiler produces platform-independent code by compiling Java code to an intermediate state called, byte code, that gets translated to machine language by a platform specific Java Virtual Machine. This arrangement buys the considerable advantage of platform independence at a significant cost in performance.