Notes on installing and using Martin's software
A version of Martin's software suitably revised for use with Visual C++ is in
components.zip. This should be unzipped into a
directory called components adjacent to any C++ source directory that uses the components.
The revisions consist of renaming all .cc files to .cpp, and changing
all #include *.cc to #include *.cpp. Also, the language repairs noted
below have been performed.
The remainder of this page is from old notes and apply only if you want to go
back to the original source supplied by Martin.
The software archive at http://www.objectmentor.com/freeware/components.txt
is a uuencoded, gzip'ed tar file. WinZip can handle this in three stages, but a simpler
WinZip version of this file has been prepared for local distribution
from this site. However, the local version has a slightly deeper directory structure,
being rooted in samples\62286.
The component library described in Chapter 2 is of special interest from the design
point of view and useful in practical applications as an alternative to the Standard
Template Library and the container portions of the Microsoft Foundation Library. Here is a
brief description of the problems encountered in making the component library work for the
prime sieve program in Listing 2-57, page 150, Chapter 2.
- Using WinZip, unzip martin.zip into a suitable directory. We
will assume the directories after dearchiving are located in \samples\62286
- Using Visual C++, create a workspace directly in \samples\62286.
- Using Visual C++, create a "Hello World" Win32 Console Application without MFC
support called "sieve" in a subdirectory of \samples.62286.
- Remove the stdafx.h and stdafx.cpp files from the project (select a file and press DEL
from the Files tab) and turn off precompiled headers in the C++ tab of the
Project|Settings dialog.
- Replace the contents of sieve.cpp with the following code.
#include <iostream.h>
#include "../component/u_set.h"
using namespace std;
int main() {
UnboundedSet<int> fSet[4];
return 0;
}
This is enough code to exercise the component library. On compiling, several
errors will occur that will have to be addressed. You will notice that included files
might not be found. As well, obscure syntax errors and operator warnings will
appear.
- The files in the archive are all named using a .cc extension. It is difficult to add
files with this extension to Visual C++ projects because the latter is looking for files
with the .cpp extension. Many of the component library's .h files #include source files
directly. This is unusual but acceptable as the source files contain definitions of
template member functions which cannot be precompiled. If all this becomes a problem, it
can be dealt with by renaming the .cc files to .cpp files and changing the #include lines
in the .h files.
- In one of the iterator classes there is a friend relation to another class. Both classes
are template classes and the Visual C++ compiler apparently deals with this particular
situation in different ways than the compiler used by the Martin. Here is an abstracted
version of the problem.
template <class T>
class A {
friend template <class T> class B<t>
...
}
template <class T>
class B { ... }
This example will give a syntax error in the line with the friend keyword, complaining
of an unexpected '<'. The problem is that class B, regardless of
whether it is a template class or otherwise, has not been defined. The fix is to declare template
<classT> class B in a forward reference and remove the templace<classT>
from the friend reference..
template <class T> class B;
template <class T>
class A {
friend class B<T>;
...
}
template <class T>
class B { ... }
- With the above repair, the program should compile with just warning messages. When read
carefully, these explain that a prefix ++ was substituted for a postfix ++. The lines of
code associated with the warning message use the postfix ++ in a standard iterator
for-loop.
for (Iterator<T> i(x); i; i++)
The warning could be fixed by changing i++ to ++i. But a better fix is applied in the
definition of ++. There is a difference between
void operator++()
and
void operator++(int)
The former defines a prefix ++ and the latter defines a postfix++. The operator
definition in question is in class Iterator in components/itercont.h. The actual code used
by Martin is
void operator++(/*int*/)
indicating that he, too, had some porting problems with this code at one time. The
repair is to remove the comment delimiters around the operator argument and allow the
operator to be declared as postfix. Note that in this case, the void result guarantees
that operator++ will never be used in an expression, so the prefix and postfix forms have
the same effect. The Visual C++ compiler is smart enough to figure this out and thus is
able to use the prefix operator in place of the postfix operator but produces a warning to
say that it took this action..
After you have compiled the small piece of sieve code with no errors or warnings, enter
the rest of the code from Listing 2-57, page 150. It should compile and run correctly.
|