#What SHOULD and SHOULD NOT be put in CPP header files?
176 messages · Page 1 of 1 (latest)
When your question is answered use !solved to mark the question as resolved.
Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.
header files are just copied and pasted into cpp files with #include so yeah, you technically don't need them
you could make a program with only cpp files, but it would be a mess to maintain
Unless your public API handles the class by pointer, you must have its full definition before using it.
I've been told it's a lot faster to compile though
What's an ABI?
also what qualifies as "before"
can I get away with having the definition in a separate CPP file
or should I just put them in a H file at that point
although the issue with that is needing to have #include inside the H file
here's an example from some code i currently have:
// token.h
#pragma once
#include "files.h"
class PBT {
public:
File file; // from files.h
void RemoveFluff();
};
yeah it's probably quite a bit faster to compile, but what good is that when you spend hours maintaining that mess and manually copying and pasting inline functions and whatnot
not having to wait so long lol
with just hours of work, you can save seconds of compilation time

i really do hate it
plus i hate getting errors like these
stuck on this atm
aaand fixed
anyway, i'd rather avoid headers if i can help it
but in that case, i could modify my question a bit
What SHOULD and SHOULD NOT be put in CPP header files?
i get not wanting to have excessive inline and whatnot
but are there not some things that can do fine without a header file
for example, if i have a function:
std::string LogError(std::string message);
std::string LogError(std::string message) {
std::string buffer = "> ERROR: " + message + "\n";
std::cerr << "\033[31m" << buffer << "\033[0m";
return message;
}
is this fine?
is the first line even necessary? (i think it is, but honestly idk with C++)
the point of header is to have consistent declarations/definitions across multiple source files
by default if you exclude stuff like template and inlines, then headers should only contain declarations + classes
if you start throwing in inline stuff then you can have inline definitions
that's a prime example of something that is not allowed in a header
first line is redundant with the second
first line is a declaration of a LogError function
second line starts the definition of that function
the definition doesn't need to have a declaration as it can serve as it's own definition
so that i can get rid of the header
and why would you
compile time 
in a cpp file you don't need the first line
but to use it across files
that's stupid here because having the one header with the declaration won't impact your compile time unless you pull everything from the internet
like you'd have to have 100s of header indirectly including one another pulled over the network or something to start feeling the impact
you almost certainly have those files on your local disk
and based on what you're saying I doubt you have a ton of inline/template code
or that you're compiling your entire project multiple times per second
well, that's the thing
I want to avoid having headers unnecessarily including each other
which... you can do by just using headers normally?
which i'm already starting to get thanks to classes using types from other classes
or functions
you inherently have to include the class definition in order to make use of the class definition
and not doing that via headers is the best way to break things
is it not bad practice to have #include within headers though
because the moment an "upstream" class change, it must be changed consistently across the entire project
no
that's a guideline from C
oh.
it's better if you can limit the amount of includes within header imo
it's stupid to ban includes within headers
if your aim is to remove any and all includes from your headers you're quickly gonna run into unmanageable and unmaintainable stuff
if your aim is to limit the amount of includes to what is strictly necessary then sure
so my question is how, then
i'll send 2 files for example
you include what you use, period
no but
you have a class as member in another class, you include the header defining the class
i assume i should not be including iostream in this header file
nor fstream, filesystem, etc.
the stuff you use only in the cpp you include only in the cpp
wait a sec
can i do...
this:
// header file
class File;
// cpp file
class File {
public:
fs::path path;
std::string extension;
std::string name;
std::ifstream raw;
std::vector<char> data;
std::ofstream file;
int LoadFile(fs::path argv);
void WriteVectorToFile(std::vector<char>& data);
};
the namesapce alias I'd rather you don't put at namespace scope or at least would do that in your own namespace, but if you're the end program then I guess
for std::ofstream you have it as member so cannot just kick out iostream
you need to get the definition for std::ofstream from somewhere
though I guess you could grab it from something smaller than iostream
need, but it still slows stuff down
is this valid?
would solve everything
otherwise uh
actually you have ofstream so arguably you'd kick out iostream and just include fstream
valid in what sense
if you ever hope to be able to use the class File in other file then absolutely not

the only file that can ever make use of File (as a complete type) is the source file
because that's where you put everything about it, aside from File naming a type
like class File; just says that File is a valid name/identifier and that it names a class, you can do nothing from that
except using it as a type name
and using it like an incomplete type
so you cannot call its member function
you cannot create any instance
you include what you use
that's it
hm
that's annoying then
that means any CPP that includes the header will also copy the other libraries
define "copy"
header includes are meant to include declarations first and foremost
- classes
"copying" other libraries mean little in that context
if you have implementation details they in most case shouldn't be in your header, and if you want to break the chain of dependencies sometime you have to learn how to work around incomplete types
I was told that having headers include other libraries slows down compile time
but that has other cost
come back when you have actual compile time problems
i do...
i mean, i've scrapped that project to start afresh
but i want to avoid that road
what kind of problem did you actually have
including too much is an issue but if you put everything as member you also don't have a choice in the matter
time
over 30 seconds to compile
and it only got worse from there
it adds up when you're needing to test things multiple times in an hour
especially as someone still learning and therefore needing to trial stuff for the sake of figuring things out
I woudln't even call that a problem, but how many files and loc/file did you even have
and how much inline/template code did you have
and were you using header only libs
not many
iirc 11 files in total
no inline, a few templates
what build system
terminal
11 in parallel in 30s sounds weird
g++
like what, did you type a command to compile everything in one go with *.cpp or something?
nope, just named every .cpp
same thing
well that's one factor but assuming you had reasonably sized source files, and didn't include a ton of other header only libs that's abnormal unless you have a potato computer
my computer is fairly potato
but it's quick in other, smaller projects i've done
i think the header files are the source of my torment
it'd be less of a hassle if you had incremental builds, maybe
i've been told those are a real hassle to manage
and, although i don't understand the concept fully, it sounds like something that wouldn't work if you constantly go back and edit older files
does someone know how to code a recursive program that switches every number 9 with a 7
idk how you stumbled into this post, but wrong place to ask
@regal oxide Has your question been resolved? If so, type !solved :)
i’d like a list or something to answer the post’s question…
that's why you learn how to use a build system because they deal with all of that for you
for basic stuff you don't even need too much
that's not how this works, or I don't understand what you're describing
one of the point of incremental builds is you only build/rebuild the part that were changed/impacted
instead of going through everything all the time
if you have the one god header that is included everywhere then yeah if you change something there you rebuild everything, but that's also kinda the point, you rebuild the impacted parts
also I'm not sure how g++ deals with multiple source files being passed at once, but usually you want to have the various source files dealt with in parallel
a proper config should provide you with that
now when you're working on a "component" you should only recompile a couple of files instead of the entire universe
as to whether your headers are structured in a way that favours short recompiles or not, that's way beyond the scope of what I've just described
having a good structure and having headers be as independent as possible is something that's hard to teach/explain
and it's arguably easier to discuss that with proper code to look at
I can throw generalities over things to do/avoid but considering you have to confront that to the actual project you're working on, it's hard to say anything meaningful that you can just blindly apply
if you meant visual studio you can navigate the gui or click the green arrow at the top to start the debugger
which will recompile/refresh if necessary, before starting up the program
if you meant vsc then that's a different story
the button is greyed out though
weirdly
If you want to you can copy paste your files into the project directory, and use the GUI to "add existing files/items" instead of creating new files from scratch
I'm referring specifically to step 4
Or you learn cmake I guess but I guess part of the point was to bypass that step by relying on what vs provided
