Implementing a configurationfile Class
I n general, the single greatest bit of functionality that C++ has to offer is inheritance — the transfer of characteristics from a base class to its derived classes. Inheritance is the ability to derive a new class from one or more existing base classes. In addition to saving some coding labor, the inheritance feature in C++ has many great uses; you can extend, customize, or even limit existing functionality. This Technique looks at inheritance and shows you how to use multiple inheritance — a handy (but little-known) capability that combines the best of several classes into a single class for the end user. To really understand what’s going on here, you have to understand something about the way that C++ compilers implement inheritance — and how the language takes advantage of this approach.
For the purposes of this example, assume that you want to implement a configuration file class. This class will allow you to store configuration information for your application in an external file and access it in a consistent manner throughout your program source code. I’m just going to explore the idea of creating a single functional class out of “mix-in” classes that do one thing very well and then move on. (As M*A*S*H would say, “Thank you, Doctor Winchester.”) When you think about it, configuration files have two basic sets of functionality — a set of properties (representing name and value pairs) and a file manager (which reads and writes those pairs to and from disk). For it all to work right, you must implement the functionality for your class in exactly that way: first the properties, then their management. You should have one base class that implements the property management, and another one that works with the disk file itself.
Destroyedjust yet. There’s no real way of knowing down the line whether this will always be true, so you may as well assume that the destructor will need to do its cleanup work at some point. You are building this class intentionally as a base class for inheritance, however, so it only makes sense to make the destructor virtual. If your destructor is virtual,all derived classes will call the base class destructor as the last part of the destruction process, insuring that all allocated memory is freed.
Note that this class makes use of the Standard Template Library (STL),whichI show you in greater detail in Part V of this book. For now, you can simply assume that the vector class implements a generic array that can be expanded. The vector class requires no minimum number of elements, and can be expanded as far as memory permits. Our property class will form the basis for a series of property types, all of which could handle differment types of properties. In addition, this class can be used as a base for other classes, which need the ability to store property information. There is really no magic here; you can see that the class simply holds onto property sets and can either add them or give them back to the caller. Note, however, that you have implemented a virtual destructor (see 1) for the class — even though nothing in the class need.
Once again, you implement a virtual destructor for your class because it’s intended as a base class for inheritance; no point getting specific about what to destroy just yet. You do, however, have a real use for the destructor, because the file pointer that opens in the constructor has to have a corresponding closing instruction (filose) to free the memory and flush the file to disk. With the virtual destructor in place, the only thing left to do is to combine these two fairly useful classes into a single class that includes the functionality of both and provides a cohesive interface to the end user of the class. We’ll call this combined class
Read More: Naasongs