Professional C__ - Marc Gregoire [482]
FIGURE 29-1
Chapter 17 illustrates a detailed example on how to implement an iterator for a class that conforms to the STL requirements, which means that its iterator can be used by the generic STL algorithms.
THE SINGLETON PATTERN
The singleton is one of the simplest design patterns. In English the word “singleton” means “one of a kind” or “individual.” It has a similar meaning in programming. The singleton pattern is a strategy for enforcing the existence of exactly one instance of a class in a program. Applying the singleton pattern to a class guarantees that only one object of that class will ever be created. The singleton pattern also specifies that that one object is globally accessible from anywhere in the program. Programmers usually refer to a class following the singleton pattern as a singleton class.
If your program relies on the assumption that there will be exactly one instance of a class, you should enforce that assumption with the singleton pattern.
Example: A Logging Mechanism
Singletons are particularly useful for utility classes. Many applications have a notion of a logger — a class that is responsible for writing status information, debugging data, and errors to a central location. The ideal logging class has the following characteristics:
It is available at all times.
It is easy to use.
It provides a set of useful features.
The singleton pattern is a good match for a logger because, even though the logger could be used in many different contexts and for many different purposes, it is conceptually a single instance. Implementing the logger class as a singleton also makes it easier to use because you never have to worry about which logger is the current one or how to get a hold of the current logger; there’s only one, so it’s a moot point!
Implementation of a Singleton
There are two basic ways to implement a singleton in C++. The first approach uses static methods to form a class that needs no instantiation. The second uses access control levels to regulate the creation and access of one single instance.
Both approaches are shown here, using a simple Logger class as an example. This Logger class provides the following features:
It can log a single string or a vector of strings.
Each log message has an associated log level, which is prefixed to the log message.
Every log message is flushed to disk so that it will appear in the file immediately.
Static Class Singleton
Technically, a class that uses all static methods isn’t really a singleton: It’s a nothington, to coin a new term. The term singleton implies that there is exactly one instance of the class. If all of the methods are static and the class is never instantiated at all, can you call it a singleton? The authors claim that, because design patterns exist to help you build a mental model of object-oriented structures, you can call a static class a singleton if you please. However, you should recognize that a static class as a singleton lacks polymorphism and a built-in mechanism for construction and destruction. For cases like the Logger class, these may be acceptable losses.
The interface to the Logger static class follows. Note that it uses all static methods for access, so there is no need ever to instantiate a Logger object. In fact, the constructor has been made private to enforce this behavior.
#include #include #include #include // Definition of a singleton logger class, implemented with static methods. class Logger { public: static const std::string kLogLevelDebug; static const std::string kLogLevelInfo; static const std::string kLogLevelError; // Logs a single message at the given log level static void log(const std::string&