I typically make a Types.h to define all of my types in and then include that in all of my project files. I haven't ever seen this anywhere though, so I assume it is "bad/wrong". The situation is often like this:

Consider a class Gardener that needs to know type of grass he will be cutting. Then consider a class Lawnmower that also needs to know what type of grass will be cut. What I would have done in the past is put typedef float GrassType; in Types.h and then included Types.h from Gardener.h and Lawnmower.h.

If, instead, I put the typedef in Gardener.h, then to access it from Lawnmower.h I would have to include Gardener.h, but since Gardener.h includes Lawnmower.h (so he can know what kind of lawnmower he has), that makes a circular dependency.

Is there a better way to do this than to introduce a template parameter to Lawnmower that can be set by the Gardener that owns it?

Thanks,

David

I typically make a Types.h to define all of my types in and then include that in all of my project files. I haven't ever seen this anywhere though, so I assume it is "bad/wrong".

I do that occasionally as well, though that's not proof that it isn't "bad/wrong". ;) It's not so much the idea, but the extent that matters. Putting all of your type definitions into a header for the sake of keeping them centralized, regardless of whether that makes sense, would be a design stink. But centralizing related type definitions that are used in multiple translation units is sensible.

Consider a class Gardener that needs to know type of grass he will be cutting. Then consider a class Lawnmower that also needs to know what type of grass will be cut. What I would have done in the past is put typedef float GrassType; in Types.h and then included Types.h from Gardener.h and Lawnmower.h.

My gut reaction is to ask why Gardener and Lawnmower care about the type of grass. But let's assume that it makes sense for them to depend on the type of the grass, wouldn't that be a reasonable place for a template?

Is there a better way to do this than to introduce a template parameter to Lawnmower that can be set by the Gardener that owns it?

Redesign your classes so that the type of grass doesn't matter? ;) For this abstraction, I really don't see the need. The only thing that would matter to the gardener (in my black thumb opinion) is setting the lawn mower's blade height.

Edited 5 Years Ago by Narue: n/a

I agree with Narue.

Collecting a bunch of "fundamental" types into one header file is fairly common, as long as those types constitute a cohesive group of related types. The fact that you cannot find a better name than "types.h" sort-of hints to the fact that they do not form a meaningful cohesive group (btw, you will need a header-guard that is more specific than TYPES_H, otherwise you might have problems later). In theory, if you stick to the one-header-one-class rule, then this whole thing of circular dependency won't be a problem at all, but it certainly can seem a bit wasteful to have one header for one typedef. But again, if later you decide to make the GrassType a bit more complex (some user-defined class), then it will be more convenient if it is in its own header.

Collecting many types into one header can also cause great grief to the building process. The header file in question sort of becomes one file on which a huge amount of other files depend on. This means that anytime you change something to this file, it will trigger a complete rebuild of all code, including stuff that is absolutely not related to the change that you made. This can get really annoying at times, if the code-base is large. The more fine-grained your headers are, the less unaffected code you have to rebuild when small modifications are made.

But, definitely, the situation seems to mandate the use of a template. Not necessarily that Gardener and Lawnmower need to be class templates, maybe a member function templates are all that is needed. It will be pretty inconvenient in the future if you want to test different types of grass, or worse, do it in one program. Templates are perfect for this. I mean, that is exactly what templates are for, automatically manufacturing classes and functions whose actions depend on the types they act upon or contain. How is that not exactly tailored to the situation you described?

This article has been dead for over six months. Start a new discussion instead.