Hmm, I've been using relative includes (stuff like ../Utilities/Bla.h) for ages. The file doing the including would be part of the same module / package / whatever you want to call it as the included file. Can you elaborate on why this is considered a bad idea?
Well, it certainly works which is the most important thing, so don't feel pressure to change
I can't speak for SimonForsman, but I avoid relative inclusions for a couple of reasons.
First, when you write '#include "../abc.h"' is the path relative to the header doing the including, or are include paths taken in to account? Is this the same across all compilers? I honestly don't
know, but I suspect include paths are looked in before abc.h is sought relative to the directory of the file doing the including. It's something you can look up of course, but In my case I'm targeting three operating systems and five or so compilers, so I'd rather not have to worry about that kind of thing. YMMV.
The second reason can be illustrated by using the O.P's hypothetical situation. Suppose we have:
- Character.hpp // contains abstract base class
- Monsters/Goblin.hpp // class Goblin : public Character { ... }
- Monsters/Dragon.hpp // likewise
- Monsters/Mutant.hpp // likewise
- Monsters/Houndeye.hpp // likewise
In Monsters/Goblin.hpp, for example, we could have '#include "../Character.hpp"'. Again, that's fine and will work, but if I later decided that I'd like "Game" to contain only the more general engine code and move the specific monsters out in to a separate project that's built on top of the engine module, I have to change those include paths. It sounds rather hypothetical, but I end up doing this quite a lot. For example, in the past month or so, I've extracted code for the following things in to their own projects, in order to make them more reusable:
- handling unicode (#include "unicode/xxxx")
- wrapping SSE intrinsics (#include "vx/xxxx")
- timing and benchmarks (#include "chrono/xxxx")
- handling task-based parallelism (#include "hive/xxxx")
If I'd have used relative paths, I'd have had a lot of busy work to do. But all I had to do was change a couple of include paths in what were the surrounding projects and everything continued to work.
It's probably the case that I'm more aggressive than most about moving reusable code out in to sharable modules, but I don't think that's necessarily a bad thing