Re: .h and .cpp
Christopher <cpisz@austin.rr.com> wrote:
1) Class defintions go in their own .h (or .hpp for templates) file
named after the class
I never use ".h" as a file name extension for C++ headers for a rather
obvious reason: It's not C code and I want to distinguish C code from C++
code unambiguously. Also, I don't see why headers containing templated
code should be named differently from headers that don't.
From unix I am accustomed to using .cc and .hh extensions, but that's
another story.
1a) Every class should have its own .h (or .hpp for templates) file
You are polluting the global namespace this way for classes that could
well be compilation-unit-local. Such classes should go into a nameless
namespace, which is incompatible with a public header file. (Ok,
technically speaking you can put a nameless namespace in a header file
because, after all, it's just C++ code like everything else, but the
advantage of doing this is dubious. You will only be including it in
the compilation unit where it's used, and including it anywhere else
would be useless, as it would only define an unimplemented local class.)
You might have learned otherwise, but I have learned that public interfaces
should be as minimal as possible, and polluting the global namespace with
local types is not good design.
1b) A .h file should never contain class implementation (except for
inline functions or methods)
That's a null statement. If a header file contains implementations,
they will be inline by necessity (else you'll get linker errors if the
header is included more than once), so that rule isn't really saying
anything.
Perhaps if you had said: "A header file should contain inline function
implementations only if there's a very good reason for them. Otherwise
they should go to the correspondent compilation unit."
2) Class implementations go in their own .cpp file (except for
templates)
Technically speaking templates can be declared in a header file and
implemented in a compilation unit even in cases where the template is
used somewhere else besides that compilation unit (yes, even without
support for export; it can be done with explicit template instantiation),
but that's not a usual circumstance. But I digress.
2a) A .cpp should never contain a class definition
Why not? If a class is used only in that one compilation unit, and
especially if it's small, what's the problem?
Think about this: What would be the difference between a private inner
class and a class local to the compilation unit (ie. in a nameless namespace),
except for scope? Would the former be ok but not the latter? Why?
(The testability argument doesn't hold because you cannot test a private
inner class from the outside.)
(And please don't tell me you oppose private inner classes too.)
3) One should not define multiple classes in a single .h file
If two classes are relatively small and strongly related to one other,
why not? A typical example would be a template class and a specialization
for a specific template type. If you put them in separate header files, you
would have a small problem in what to include. There are many non-templated
examples as well.
3a) Nested class defintions should be avoided without good reason
(what's good reason?)
I don't see why inner classes "should be avoided".
In general class design should be as simple as possible. That includes,
among many other things, minimizing the amount of inner classes. However,
there's nothing special about them in particular that should be avoided.
Iterators are good examples of public inner classes. Why should they be
avoided? And if some private implementation of the class needs a private
class, then why not? (In fact, sometimes trying to religiously avoid inner
classes can make your code much more complicated and harder to manage.)
6) Variables should never be defined in a .h file
There are some situations where extern variables are justified. Although
even in those cases they should usually be declared inside a namespace to
minimize global namespace pollution. (std::cout would be an example.)
7) Globals should not be defined in a .h file
Well, duh. You'll get a linker error if you do. (At least if you include
the header in more than one place.)
8) Every .cpp file should compile into a .obj file without error or
warning on its own.
Hmm, is there any other way? Or what do you mean "on its own"? I don't
even know of any other way of compiling a C++ program than one compilation
unit at a time.