2

I'm sure there's been questions like this asked, but I simply could not find them. I was probably using the wrong words, and if so, a point in the right direction would be awesome and I will just delete this question.

Anyway, I am making my first 'larger' project and I now have a plethora of files that need to be included into other files for the project to function. The problem is that including all these files looks extremely messy and could lead to unneeded includes/bugs. For example of what I mean;

Say I have a class called Spell in a file called Spell.h & Spell.cpp that holds general information for all spells (mana cost, cast time, ect) and then a bunch of different specific spells that inherit from the Spell class, all in their own separate files. I need to include these spells in the Enemy and Character class so that they can have a list of usable spells, but to do so would mean I need to individually include each specific spell I need. That sounds tedious and gross.

I'm wondering if theres a way that I can simple call something like '#include "AllSpells.h"' or '#include "CharacterSpells.h"' that will then include all the files I want included.

I know I could create an empty class that includes the needed specific spells and just include that class instead (e.g. have a class called AllSpells that #includes every specific spell) but that also sounds bad.

It seems like a pretty common thing to do, and as such it would make sense that there is a 'best' or list of 'best' ways to do such a thing. Thanks so much for any advice here.

Cool Dudde
  • 33
  • 6
  • 1
    Just create another header file which includes all your spells and include this file in your Character/Enemy class. You don't need an empty class. – taminob Feb 15 '19 at 06:37
  • 1
    *a point in the right direction would be awesome and I will just delete this question.* doing this is the antithesis of Stack Overflow. If it's a duplicate, it'll get closed as a duplicate and you'll get a link from the deal. If you get answers, leave them for future programmers. If you get a barrage of downvotes, well, then the question was just not meant to be. – user4581301 Feb 15 '19 at 06:38
  • 2
    My suggestion would be to see if you can take full advantage of polymorphism and write all of the spells so that the user of the spells never need to include anything other than spell.h. Hide everything behind the abstraction `Spell` presents and perhaps a factory to construct the specific spells. – user4581301 Feb 15 '19 at 06:48
  • @user4581301 I've noticed this a lot lately, users closing their own questions once they've got an answer. I wonder why it's suddenly started happening? – john Feb 15 '19 at 07:01
  • Can't be sure since I can't actually see the code but polymorphism sounds like the way to go. – john Feb 15 '19 at 07:04
  • To answers a few questions at the same time; By empty class I meant just header file. I intended to delete only if I was just asking the wrong question and there was a better place/way/link to the answer. I dont think I can do this because certain types (subclasses of the character and enemy) get specific spells on creation, and I need a way to call spell functions (I might be wrong but I dont know another way to do so other than #including) – Cool Dudde Feb 15 '19 at 07:07
  • 1
    There is no "best" way to include all header files for subclasses - good technique is usually considered to involve making classes (like `Character` or `Enemy`) unaware of `Spell`s subclasses. Instead, set up `Spell` as a polymorphic base class, have subclasses specialise virtual functions provided by `Spell`, and have `Character` use virtual function dispatch. If `Character` needs information to decide whether or not to cast a spell, have the `Spell` class provide functions so it can be interrogated (e.g. to check if a particular spell can be cast at a particular type of enemy). – Peter Feb 15 '19 at 10:18
  • @john [Speak of the devil?](https://stackoverflow.com/questions/54718066/segmentation-fault-when-attempting-to-set-cur-node-root-node-next-libxml2) – user4581301 Feb 15 '19 at 23:17

1 Answers1

1

I offer the following coding guidelines that will hopefully help you decide whether to #include a .h file in a .cpp file.

  1. I find the Open-Closed Principle one of the most valuable principles. If you need to modify existing files to support a new type of Spell, you are in violation of this principle.

  2. If you can get away with using a forward declaration, use it. Don't include the .h file. See When can I use a forward declaration? for more info on the subject.

Regarding

I need to include these spells in the Enemy and Character class so that they can have a list of usable spells, but to do so would mean I need to individually include each specific spell I need. That sounds tedious and gross.

That is not gross, it is essential and appropriate. It maybe tedious but that can possibly be addressed by taking a fresh look at your code, and figuring out whether you can get by without needing to explicitly reference sub-types of Spell.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Sorry for the wording, I meant including each individual spell file, and if I have, say, 25 of them then it would be gross. I have used some forward declaration but in some cases I need access to the spell's functions. If I'm not mistaken, forward declaration doesn't give me access to the classes functions. Additionally, some subclasses of the character and enemy need certain spells initialized on initialization. Actually, I could just include those specific spells that are needed on initialization and have a function in the parent Spell class that calls the functions of the subclass spell. – Cool Dudde Feb 15 '19 at 07:12
  • @CoolDudde, that points to a potential flaw in your design. The way I read your comment, if you need to add new sub-type of `Spell`, you'll most likely have to come back to a working file and modify it. That violates the Open-Closed Principle. If you haven't looked at design patterns, this might be a good time to dive into it. – R Sahu Feb 15 '19 at 07:16
  • @R Sahu Thats an interesting idea, and I'm not entirely sure I've fulfilled it, but I do think I have. I can't see any other way to make specific enemies and characters have specific spells other than including the needed spell with that enemy/character. That said, I dont think I'll ever have to modify a spell or the `Spell` parent class to add it to any enemy/character. Likewise, I dont think I will ever have to change an enemy/character to include a spell (other than simply initializing the spell with enemy/character). I think that is what the open-closed problem addresses. – Cool Dudde Feb 15 '19 at 07:30