3

I have a base class called EventArgs. Derived from this are many, many specializations that represent event arguments for a particular kind of event. Consumers of these events may need some, many, or very few of these argument classes.

My question is, would you provide a header file for each type (e.g, 50+ header files for the varying ones), would you try to group them in to families and have a 'common' header file for those, or would you throw caution to the window and throw them in to one easy-of-use header file that can just be included?

Another approach might be to have 50 header files, and then I could introduce some "family" header files that included particular ones. Not sure about the naming conventions for these kinds of things so it is obvious what is where.

I know there may not be a hard and fast rule, but wondering what other developers have done when they find themselves writing many little classes.

Thanks in advance.

Moo-Juice
  • 38,257
  • 10
  • 78
  • 128

5 Answers5

3

I would have to put two classes into separate headers in one of the following cases:

  • they are huge
  • they are unrelated or unlikely to be used together
  • each of them introduces its own header dependencies

Otherwise, it does not make much sense to separate them. I know some people have this "one class per header" rule, but it does not look reasonable in your case.

What is for "families" including plenty small files, in certain build systems (and file systems) this might have impact on compilation time, and in any case I don't see a point in doing this - usually people will use documentation or IDE to find classes, not looking at headers file names. So you would only do that to simplify inclusion, but then why not putting them into the same header.

Roman L
  • 3,006
  • 25
  • 37
  • A good point. Many of these "little" classes have completely different dependencies. Apples and Oranges. The "put them in groups" sounds good, in theory, but as I commented on krakover's solution, there are a good number that have no family but themselves. Where is the line drawn? – Moo-Juice Jan 05 '11 at 00:54
  • @Moo-Juice: I would probably separate them in case of completely different dependencies. Again, it depends, because if dependencies are different but "dependency depth" is very small (e.g. one depends on Apples, another depends on Oranges, but both are just structures with no other dependencies) it might be better to group them – Roman L Jan 05 '11 at 00:58
  • This is pretty much the strategy I'm using right now. I'm working through a chip-vendor-provided USB stack (not one of the _HCI ones) which looks like it was written by summer students. It has a separate file for each descriptor type and each request type. Most files are 50 lines of software license and 2-6 lines of `#define` constants. So I collected all the requests into one .h file and all the descriptors into a .h/.cc pair (I'm converting the stack to C++). Much easier to read now, fewer open windows and a directory is replaced with three files. – Mike DeSimone Jan 05 '11 at 01:33
  • @Mike: unrelated but... I certainly hope you're converting the `#define` to real constants while moving up to C++ :) – Matthieu M. Jan 05 '11 at 07:48
1

I would group them in families according to classes that users would likely want to use together. 50+ tiny header files seems excessive in any case.

krakover
  • 2,989
  • 2
  • 27
  • 29
  • This was my first thought, too. Then I realized there were 'rogue' classes, derivatives that don't have families and that are pretty much stand-alone. My thought process was, if you go down the family-route it should be apparent which include files have what... except for the stray ones. Although 50+ header files seems excessive, at least you have a common rule of "include the ones you want to use". This is my current dilemma :) – Moo-Juice Jan 05 '11 at 00:46
  • I don't see why you can't have "families" of one when needed. It still cuts 50 files down to much fewer. – Mike DeSimone Jan 05 '11 at 01:29
0

Couldn't all the variants be templates?

David
  • 3,324
  • 2
  • 27
  • 31
  • Well, each derivative has completely different members and accessors. Apart from the common base-class, they have nothing in common with one another. The base-class is there so they can be passed in to a functor. – Moo-Juice Jan 05 '11 at 00:44
0

I've been in a similar situation where I was developing a GUI library. Initally all components (they were small classes) were sharing the same header and source file. This worked pretty well. I later attempted to put them in separate files but it really didn't improve anything. It only added the burden of spending a lot of time searching through these files.

That aside, maybe you can draw some inspiration from Poco C++ library. This library usually follows the one class per header idiom, but there are exceptions. For example the entire exception hierarchy is coded on one header and source file using a macro based system (see Exception.h and Exception.cpp).

StackedCrooked
  • 34,653
  • 44
  • 154
  • 278
0

if they belong to same inheritance hierarchy, put them to the same .h file. It helps you decide correct order for the classes. One of the less known compile-time checking in c++ relies on the correct order of classes in .h file.

tp1
  • 288
  • 1
  • 3