James Kanze
12/8/2008 1:31:00 PM
On Dec 8, 10:46 am, Martin Drautzburg <Martin.Drautzb...@web.de>
wrote:
> jason.cipri...@gmail.com wrote:
> If the definitions are
> > outside the declaration, it is entirely up to you what
> > source files you want to put the definitions in, although
> > personally I find it easiest to stay organized if every
> > class has a dedicated header with the declarations, and a
> > source file with the definitions.
> That the way you have to do it in Java and it does help
> somewhat. What I don't like about it, is that you may hesitate
> to create an extra class, because you have to create two new
> files in C++ (one file in Java, except you are doing EJB
> stuff, where you have to create four files).
That's not totally true. C++ doesn't impose any particular
organization: you could put all of your classes in a single
header file, for example.
Good design generally suggests that header files be both minimal
and complete---typical requirements for a class, so there is a
tendency of one class/one header. But there are certainly
exceptions; if you have two classes that can only be used
together, then it makes sense to put them in a single header,
and if one class is only used to access certain features of
another, it makes sense to make it a nested class. (A good
example of the first would be invasive reference counting, where
all of the objects pointed to by RefCntPtr<> must derive from
RefCntObj. A good, and very widespread, example of the second
would be iterators or proxies.)
How the source files are divided up depends a lot on what you
are doing. In a well written, general purpose library,
practically every non-virtual function will be in a file of its
own. In other cases, it makes sense to both define and
implement helper classes in the same source file as the class
which uses them.
In the end, the organization should be based on sound
engineering principles. And there's no real reason to worry
about the number of source files, or even the number of header
files, involved; it normally doesn't take any more time to
create a function in a new file than to create it in an existing
file.
> This is something I really like about e.g. Python: creating a
> class is not more work than creating a function, so it does
> not require any discipline to put something into an extra
> class if that makes things clearer.
C++ is statically typed, and designed for large projects. This
means that in many cases, the person who defines the public
interface will not be the person who implements it; it will also
be reviewed at a different level.
> But the one-class-one-file idiom creates another problem: when
> you create lots of little classes, you cannot see what
> *classes* belong together. You need another structuring
> element. I suppose you can use directories for that. Again
> this is what they do in Java and I don't particularily like
> it. It just scatters things too much.
Finding a good multilevel organization is an art, and no matter
what you do, you'll end up thinking that some other organization
would have been better. I'm not sure to what degree this is a
reflection of the truth, and to what degree it is just "the
grass is always greener on the other side of the fence."
> I recently started using Doxygen for documenting my code and
> it does a good job on structuring things. There I *can* group
> classes into modules and member functions into member
> categories which makes the whole thing a lot more
> comprehensible. It is really fun reading that documentation
> and it even lets you find flaws. I only wish I could come
> close to that browsing experience with eclipse's CDT C++
> tools.
Yes. Doxygen is very good in that respect. The only real
problem is that it requires you to work backwards. You normally
want to have the documentation before you start writing the
code, at least where interfaces are concerned.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34