So I understand the concept as it’s explained, and it makes sense. But if we know that the header class is only ever going to be used in derived classes, wouldn’t we just want to go ahead and include all the necessary headers in the base class? Or is it still better to design this way in order to give it more reusability in the future?
How do you know that? Do you have every piece of the entire project outlined and never deviate from it?
Also having all the includes in the base class’ header would mean they are also included in the derived class’ header.
I mean yeah, exactly. By the rules of inheritance, whatever is derived from a base class ideally should have that, right? If you’re going off of the “Is-A” mindset of derived classes (every Dog is an Animal), then that makes sense to do it that way. If I know everything deriving from class A is going to have a member variable that is of class B, and will need to actually do something with said member variable, then don’t I need to have access to that then in each one of the derived classes in order to actually use said variable, and therefore should have the class B header file included? You can’t use the class B member variable without including it anyways.
Yes, actually, I do. The first video in the series introduces exactly what this project outline is, and the instructor said exactly which classes are going to be derived from this base-class. From there if I choose to change/extend it, then that’ll be my prerogative when that time comes. Also, that’s how base-classes for games work. There’s no just generic “enemy” or “gun” or whatever, but those things all derive from a base “enemy” or “gun” class (probably a virtual class) to get common member variables and functions. Please don’t belittle me or treat me like I don’t know anything just because I’m asking a question.
The whole point of my question is if it’s better industry-practice to simply include files in a header that I anticipate will always be needed in a derived class, or if it’s better practice to just include them inside of every single derived class in the off-chance that maybe one of them won’t need it (obviously this depends on the context of what it is that the Class itself is and what it does). But your base-class should, ideally, be designed in a way such as that it won’t include unnecessary member variables for any of its derivatives, correct?
Using this project. for example. I know that anything that uses this pawn class is going to need a Capsule Component, by virtue of it being declared as a member-variable in the base-class in the first place. That’s simple logic. If I wanted a Pawn without a Capsule Component, why would I base it off of the base-class that I know includes that component? It’s a waste of memory so I wouldn’t, and I would instead find some other solution. So, knowing this, does it not also then make sense to include that header file in the base-class then, or is there a reason why we should use Forward Declaration and then include it in every single derived class? Which sounds like it’s more work for no performance/readability payoff.
If the reason is we’re afraid of including the same header more than once in a translation unit, that would be easily solved with a simple #IF-#ELSE or #pragma once pre-processor block. Or is it so that we keep our base-class as clean and simple as possible? Perhaps it’s more efficient on a low-level to do it the Forward-Declaration way, I don’t know. That’s WHY I’m asking.
Sorry, in the OP you said you understood the concept so I answered accordingly. Based on your reply I don’t think you do or perhaps I misunderstood what you meant by that?
Right, but you seem to only be thinking about this via the perspective of Derived.h and Derived.cpp. My point was that you are forcing all files that #include "Derived.h"
to also include those files, whether or not it needed them.
Say for example I have a Vehicle class and a Car class that inherits from it. Then somewhere in my code I want to call a function that only exists in Car and nothing else from Vehicle or Car (like Meshes, Wheels, etc) then by having them be included in Vehicle.h means the prepocessor is doing extra work for no benefit.
Preprocessed output including everything: (using <algorithm>
to simulate “including everything the class needs” as it’s a large header):
- Compiler Explorer - (+28k lines)
vs using forward declarations (removing the include):
- Compiler Explorer
I think you may have missed the “and not deviate from that” part. Once you start developing something you get a better sense of everything and may see your original was suboptimal or flat out won’t work. It’s rather rare to have everything go exactly how you originally planned.
I’m sorry if that’s how I came across but that was not meant to belittle you or assume you don’t know anything (I was in fact assuming the opposite as previously stated).
It’s not about unnecessary members, it’s about improving throughput and/or avoiding circular dependencies. By not #include
ing files unnecessarily.
Will the game mode? It’s included here but not used in this translation unit
Source/ToonTanks/ToonTanksGameMode.cpp · main · GameDev.tv / Unreal 5 CPP / Toon Tanks UE4 · GitLab
Does this file need to know anything about capsule components?
It’s not. It’s about including something that wasn’t needed at all. They solve different problems.
The advice to follow is:
- In a header file only
#include
what is strictly necessary. - In a source file include everything you use (this makes you less susceptible to any refactoring - yours or the engine’s).
Ah, yeah I see what you’re saying. That makes more sense now.
Sorry for making a bad assumption, I must have been having a bad day and misread the tone of what you wrote.
These seem to be good guidelines, I’ll be sure to keep these in mind!
Thank you for your help and for your replies
This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.