about headers in C++ when I should use them? - c++

Question about header files in C++: when I should use them. If I write small program should I create header file or can I just declare my classes in .cpp files? What is a good practice? If you give links to articles about it, it would be good. I could not find good ones.

Use header files when you need to share information between several source files. The header file, used carefully, will ensure consistency between a file defining some functionality and other files using that functionality.
When a program consists of a single (source) file, there is no need to create a header. When a program needs more than one source file (say two source files), there must be at least one function or variable 'shared' between the two files (because if there wasn't, one of the files would be redundant). You should have a header to describe the shared function or variables so that the producer and consumer agree on the common functionality.
The corollary is that a header should not describe anything not needed by the consumers of the functionality. Just because the implementation needs to use some second header, the consumer should not be made to include it. If the second header provides definitions used in the interface, then it should indeed be included in the common header.
OK - lots of verbiage. A concrete example:
source1.h
extern int somefunc(int, int);
source1.cpp
#include "source1.h"
int somefunc(int a, int b)
{
return a + b;
}
program.cpp
#include <iostream>
#include "source1.h"
using namespace std;
int main()
{
int x = somefunc(1, 3);
cout << "somefunc(1, 3) is " << x << endl;
}
The header here is necessary to provide the assurance that everything is consistent. Both source1.cpp and program.cpp must include the header to ensure the consistency.
Note that if somefunc() was defined in program.cpp there would be no point in providing the header.
Now suppose we modify somefunc():
source1.cpp - revised
#include "source1.h"
#include <iostream>
using namespace std;
int somefunc(int a, int b)
{
cout << "a = " << a << ", b = " << b << endl;
int x = a + b;
cout << "x = " << x << endl;
return x;
}
Superficially, you could revise source1.h so it includes <iostream>, but that would be a bad move. The interface of the function defined, somefunc(), does not depend on <iostream>, so the header should not include <iostream>.

Header files are always a good idea but strictly speaking you don't need them. Especially when using multiple .cpp files it's strongly recommended to use them.
The rule I used before "always use them" was: any cpp that has its functions accessible from other cpp files should use a header file to "export" the functions.
Best practice: always use header files.

Another reason why you should use header files
when you distributing your binaries. You provide the header file and the dll file to your clients.

Related

Does C++ include all headers a included header file includes?

In this example code, I have 3 files:
testHeader.h:
void hello() { }
file1.h:
#include "testHeader.h"
#include <iostream>
void sayHi() { std::cout << "hi" << std::endl; }
file2.h:
#include "file1.h"
void sayHello() { std::cout << "hello" << std::endl; }
If file1.h includes testHeader.h and file2.h includes file1.h, do testHeader.h and its functions become accessible in file2.h? What about <iostream> and its functions?
Unless protected by preprocessor guards in weird ways, yes, you get them all. #include is largely a preprocessor trick, roughly equivalent to dumping the text of the include into the source code, and it's transitive; if you #include <a.h>, you get the expanded form of a.h, including the preprocessor expanded form of all its includes, all their includes, etc., etc. ad infinitum, in a single pass.
Note that it's still a good idea to explicitly include all the things you rely on directly; sure, the other .h files might #include <vector> today, but that's no guarantee the next release will have them if they're not a necessary part of the API being exposed.
It's also worth noting that preprocessor include guards (and/or #pragma once) is used almost universally to mean a .h file's contents don't get included twice (by convention, not a guarantee; in the case of poorly written .h files, or weird ones designed for multiple inclusion with different preprocessor setups it won't be obeyed); there is little to no cost to re-including a header in the .cpp that it already got from a .h you included. On older compilers, without #pragma once and with no special handling for include guards, it might have to load the header a second time, see the guard, and dump nothing on the second include; many newer compilers are smart enough to avoid even that cost. Point is, don't try to optimize by avoiding redundant #includes; every file should have the complete set of #includes needed for the things used in that file, no more, no less.
If you work on older compilers, without #pragma once, then try to do as following.
--- file1.h ---
#ifndef FILE1_H
#define FILE1_H
#include "testHeader.h"
#include <iostream>
void sayHi();
#endif
--- file1.cpp ---
#include "file.h"
void sayHi() { std::cout << "hi" << std::endl; }
--- file2.h ---
#ifndef FILE2_H
#define FILE2_H
#include "file1.h"
#include <iostream>
void sayHello();
#endif
You shouldn't make a body of function in HEADER file. It might cause a compile error for multiple links for the same function. Please write function' prototype and body into Header and Source file seperately.

Header, function definitions, main in different files

I wanna make a program that's it's going to be in 3 files. "Persona.hpp" "Persona.cpp" "main.cpp" im not sure the way it can be done.
This is "Persona.hpp"
#ifndef __PERSONA_HPP
#define __PERSONA_HPP
#include <string>
using namespace std;
class Persona{
public:
Persona();
void setNombre(string N);
void setFechaNac(string F);
void setPeso(float P);
void setEstatura(float E);
string getNombre(void);
string getFechaNac(void);
float getPeso(void);
float getEstatura(void);
void mostrarDat(void);
private:
string nombre;
string fechaNac;
float peso;
float estatura;
};
#endif
"Persona.cpp"
#include "Persona.hpp"
#include <iostream>
#include <string>
using namespace std;
Persona::Persona(){
nombre = "";
fechaNac = "";
peso = estatura = 0;
}
void Persona::setNombre(string N){
nombre = N;
}
void Persona::setFechaNac(string F){
fechaNac = F;
}
void Persona::setPeso(float P){
peso = (P>1 && P<500) ? P : 0;
}
void Persona::setEstatura(float E){
estatura = (E>30 && E<280) ? E : 0;
}
string Persona::getNombre(void){
return nombre;
}
string Persona::getFechaNac(void){
return fechaNac;
}
float Persona::getPeso(void){
return peso;
}
float Persona::getEstatura(void){
return estatura;
}
void Persona::mostrarDat(){
cout << "\nNombre: " << getNombre();
cout << "\nFecha de nacimiento: " << getFechaNac();
cout << "\nPeso: " << getPeso() << " Kg";
cout << "\nEstatura: " << getEstatura() << " Cm";
}
"main.cpp":
#include "Persona.hpp"
#include <iostream>
using namespace std;
int main(){
Persona humano;
cout << "\nConstructor default: ";
humano.mostrarDat();
humano.setNombre("Jose Ramon Garibay Alvarez");
humano.setFechaNac("27 Octubre de 1989");
humano.setPeso(80);
humano.setEstatura(175.5);
cout << "\n\nEstableciendo datos validos: ";
humano.mostrarDat();
humano.setNombre("Karina Nogueira Briseno");
humano.setFechaNac("15 Agosto de 1985");
humano.setPeso(0.457);
humano.setEstatura(17);
cout << "\n\nEstableciendo datos Invalidos: ";
humano.mostrarDat();
return 0;
}
First of all i'm getting an error: http://oi40.tinypic.com/2v96quo.jpg
and i dont know if im doing right the "#including" files. I remember my profesor was using something like "#ifndef SOMETHING" but i don't know if it is necessary, Thanks for your answers! :)
Use #include "Persona.hpp" instead of #include <Persona.hpp>
Looks like you've got the wrong include directories set.
In addition, you're essentially including your header the "wrong" way, which might be the reason as well:
#include "header.h": Will look in your current code directory (i.e. where your cpp file is) first, when looking for that specific header file.
#include <header.h>: Will look in your system/predefined include directories first.
However, based on your compiler('s) settings, it's version, etc. it's possible that there won't be any difference (unless you've got conflicting file names). It's definitely a good idea to always follow the intended route:
Use #include "..." to include header files that sit somewhere in your source directory. Use #include <...> to include other headers that should be installed on the machine where you're compiling (i.e. external dependencies).
The added note about include guards (either using #ifndef and #define or #pragma once): Those should be used to prevent header files to be included more than once in the same translation unit, e.g. if the same header file is included by two different other headers, you'd end up with redefinitions of variables, structures, classes, etc.
Include guards are an easy way to prevent this behavior; you'll just have to make sure to use a macro that's unique enough.
A basic include guard could be something as simple as this:
#ifndef MY_CUSTOM_HEADER_FILE
#define MY_CUSTOM_HEADER_FILE
// Your header file code
#endif
However, you might agree that this can be rather bothersome and theoretically error prone, e.g. if someone picks common words or names like CUSTOMER or CUSTOMER_H. Due to this, pretty much any modern preprocessor will accept the pragma instruction #pragma once. If that line is in a header file (and active), the compiler will ensure that it's never included more than once:
#pragma once
// Your header file code
If you have different directories for source and header files, please be sure that you locate the correct directory. You might have to change the directory like that:
#include "../Headers/Persona.hpp"
For better programming approach in OOPS always use #ifndef directive in your .h or .hpp file.
start your .hpp like this.
#ifndef __PERSONA_HPP
#define __PERSONA_HPP
and at the ending of your file put this line
#endif
This will take care of many thing and avoid including header file many time.
I remember my profesor was using something like "#ifndef SOMETHING" but i don't know if it is necessary,
#ifndef is a header guard. It is not what is causing your problem, but here's how to use them. You put them at the top of your header like this:
#ifndef SOMETHING_H
#define SOMETHING_H
and at the end of the header you put:
#endif
It basically means that each header gets included exactly once. If you don't have a header guard, you might run into problems.
For example, if you have A.cpp and B.cpp that both #include "header.h", then when the compiler compiles the second one you will get a lot of errors along the lines of "such-and-such class is already defined" or "such-and-such variable is already defined".
But if you have a header guard then when it tries to include the header a second time the #ifndef will fail because SOMETHING_H will have been already defined (when it included the header the first time). So it will skip the whole file until it gets to the #endif and you won't be declaring variables multiple times.
This probably won't be a problem for you if you are only making small projects at the moment, but it is a strongly recommended habit to get into.

Including .cpp files

I have read in places like here that you have to include .h files and not .cpp files, because otherwise then you get an error. So for example
main.cpp
#include <iostream>
#include "foop.h"
int main(int argc, char *argv[])
{
int x=42;
std::cout << x <<std::endl;
std::cout << foo(x) << std::endl;
return 0;
}
foop.h
#ifndef FOOP_H
#define FOOP_H
int foo(int a);
#endif
foop.cpp
int foo(int a){
return ++a;
}
works, but if I replace #include "foop.h" with #include "foop.cpp" I get an error (Using Dev C++ 4.9.9.2, Windows):
multiple definition of foo(int)
first defined here
Why is this?
What include does is copying all the contents from the file (which is the argument inside the <> or the "" ), so when the preproccesor finishes its work main.cpp will look like:
// iostream stuff
int foo(int a){
return ++a;
}
int main(int argc, char *argv[])
{
int x=42;
std::cout << x <<std::endl;
std::cout << foo(x) << std::endl;
return 0;
}
So foo will be defined in main.cpp, but a definition also exists in foop.cpp, so the compiler "gets confused" because of the function duplication.
There are many reasons to discourage including a .cpp file, but it isn't strictly disallowed. Your example should compile fine.
The problem is probably that you're compiling both main.cpp and foop.cpp, which means two copies of foop.cpp are being linked together. The linker is complaining about the duplication.
When you say #include "foop.cpp", it is as if you had copied the entire contents of foop.cpp and pasted it into main.cpp.
So when you compile main.cpp, the compiler emits a main.obj that contains the executable code for two functions: main and foo.
When you compile foop.cpp itself, the compiler emits a foop.obj that contains the executable code for function foo.
When you link them together, the compiler sees two definitions for function foo (one from main.obj and the other from foop.obj) and complains that you have multiple definitions.
This boils down to a difference between definitions and declarations.
You can declare functions and variables multiple times, in different translation units, or in the same translation unit. Once you declare a function or a variable, you can use it from that point on.
You can define a non-static function or a variable only once in all of your translation units. Defining non-static items more than once causes linker errors.
Headers generally contain declarations; cpp files contain definitions. When you include a file with definitions more than once, you get duplicates during linking.
In your situation one defintion comes from foo.cpp, and the other definition comes from main.cpp, which includes foo.cpp.
Note: if you change foo to be static, you would have no linking errors. Despite the lack of errors, this is not a good thing to do.
You should just include header file(s).
If you include header file, header file automatically finds .cpp file.
--> This process is done by LINKER.
Because of the One Definition Rule (probably1).
In C++, each non-inline object and function must have exactly one definition within the program. By #includeing the file in which foo(int) is defined (the CPP file), it is defined both in every file where foop.cpp is #included, and in foop.cpp itself (assuming foop.cpp is compiled).
You can make a function inline to override this behavior, but I'm not recommending that here. I have never seen a situation where it is necessary or even desirable to #include a CPP file.
There are situations where it is desireable to include a definition of something. This is specially true when you try to seperate the definition of a template from the declaration of it. In those cases, I name the file HPP rather than CPP to denote the difference.
1: "(probably)" I say probably here because the actual code you've posted should compile without errors, but given the compiler error it seems likely that the code you posted isn't exactly the same as the code you're compiling.
Because your program now contains two copies of the foo function, once inside foo.cpp and once inside main.cpp
Think of #include as an instruction to the compiler to copy/paste the contents of that file into your code, so you'll end up with a processed main.cpp that looks like this
#include <iostream> // actually you'll get the contents of the iostream header here, but I'm not going to include it!
int foo(int a){
return ++a;
}
int main(int argc, char *argv[])
{
int x=42;
std::cout << x <<std::endl;
std::cout << foo(x) << std::endl;
return 0;
}
and foo.cpp
int foo(int a){
return ++a;
}
hence the multiple definition error
So I found that if you are compiling from Visual Studios you just have to exclude the included .cpp file from the final build (that which you are extending from):
Visual Studios: .cpp file > right click > properties > configuration properties >
general > excluded from build > yes
I believe you can also exclude the file when compiling from the command line.
I want to clarify something: including header files is not neccessary to make the linker understand what you want. You can just declare it and it will be linked fine.
main.cpp:
#include <iostream.h>
//not including "foop.cpp"!
int foo(int a);
int main(){
std::cout << foo(4) << std::endln;
}
foop.cpp:
int foo(int a){
return a++;
}
I don't encourage doing like this, but know that headers are not some magic which you have to follow to make the code compile.
Using ".h" method is better
But if you really want to include the .cpp file then make foo(int) static in foo.cpp

Good Practice, in including source files

I am using boost msm library (you don't need to know how it works) to code my statemachine, and i have a cpp source file organization question.
in the first source file (1.cpp) I define the statemachine, the event and the actions and the transition table, but I would like to define the state in another cpp file just because I would need to edit the states much more often then anything else in the statemachine.
Now what I did is that I wrote the states in another source file (2.cpp) and I included 2.cpp in 1.cpp
It compiles and everything, but its not clean at all, Id like to encapsulate this somehow..Any ideas?
Well typically you would include only .h files, i.e., the header files that declare types and the functions that you will implement in your associated .cpp file. You should not need to include an implementation file at all. Have you created any header files? Here is a basic example:
// Foo.h
class Foo {
// note that it is not defined here, only declared
public void some_function(int i);
};
// Foo.cpp
#include "Foo.h"
#include <iostream>
// implement the function here
void Foo::some_func(int i) {
std::cout << i;
}
Typically in C++ the definitions of classes and the function prototypes exist in header files (ending in .h or .hpp), with the implementation of functions existing in source files (ending in .cpp or .cxx). This allows you to expose an external interface so that other files can use the definitions used in the first file. You would make function prototypes and class declarations in your header file, and then include that header file in both cpp files.
In general, it is good practice to only include header files, and not include source files in other files.
If i were to write this from scratch (a finite state machine),
i will put following inside:
fsm.h:
struct fsm_rule {
/* state to which this rule belongs to */
int state;
/* new state */
int next;
/* is called when rule matches */
int (*fn)(int in, void *ctx);
};
struct fsm_state {
int nrules;
struct fsm_rule *rules;
};
struct fsm {
int nstates;
struct fsm_state *states;
};
and then inside fsm.c i will go ahead and implement required methods.
PS: Ofcouse fsm.c includes fsm.h

include directories vs. lib directory concept question

What is the difference between linking to include files versus linking to lib files?
I am fairly new to C/C++ and I'm having a hard time figuring out the difference between using include files and a static lib file to call functions. In my mind, the include files have functions that one can call just like .lib files.
In C++ (and C and other similar languages) a function is said to have both a declaration and a definition.
The declaration is simply a short statement that declares that the function exists, and what its interface looks like. Consider a basic function add that adds two integers together. Its declaration might look like the following:
int add(int, int);
This means "there exists a function add that takes two integers and returns an integer". It does not specify what the function actually does, despite the fact that we can make a good guess based on its name.
The definition of the function is where we define exactly what the function does. This might be what you consider to be the actual function code. Using the add function as an example:
int add (int a, int b)
{
return a + b;
}
So how does this fit with your question? Well, suppose we have a number of math functions in math.cpp:
// math.cpp
int add (int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
And also suppose we decide to use some of these in our main function in main.cpp:
// main.cpp
#include <iostream>
int main (int argc, char* argv[])
{
std::cout << "1 + 2 = " << add(1, 2) << std::endl;
std::cout << "8 - 3 = " << sub(8, 3) << std::endl;
}
If you try to compile main.cpp as it is, it will complain that it doesn't know what add and sub are. This is because you are trying to use them without declaring that they exist - which is exactly what a declaration is for. So you might do the following:
// main.cpp
#include <iostream>
int add(int, int);
int sub(int, int);
int main (int argc, char* argv[])
{
std::cout << "1 + 2 = " << add(1, 2) << std::endl;
std::cout << "8 - 3 = " << sub(8, 3) << std::endl;
}
This would work, but is not very flexible. If we add a new function mul, we need to go and add its declaration to main.cpp and every other .cpp file that uses it (which is a lot of work if you have a lot of .cpp files). So what we do is instead we put all the declarations into a single file (say, math.h) so we only have to maintain the list of declarations in a single spot. Then, we simply include math.h into any file that uses the math functions. This is the purpose of header files (a.k.a. include files).
This works great, but could be even better. As it is, we have a main.cpp file, and a math.cpp file, both of which are compiled every time you compile the program*. If your math functions don't change at all, surely it's better to compile them once and just insert the pre-compiled definitions into your executable whenever you recompile main.cpp? That is exactly the purpose of .lib files. They contain the pre-compiled code for definitions of the relevant functions. You still need the include file to let you know what functions exist in the lib.
The purpose of the linking stage of compilation is to take these pre-compiled functions and the functions you have just compiled, and roll them together into a single executable file.
Essentially, you can look at a static lib as the pre-compiled code for a number of predefined functions, and its matching include file as a tool to let any code wanting to use those functions know which are available and what their description is.
* This is not strictly true, but is sufficient for our purposes here.
To provide a simpler answer:
.lib files are precompiled libraries. If you include a .lib, you also need to include the .h/hpp header files, so your compiler knows how to access the functions in the .lib.
When you compile your program, all the functions used from the lib are only linked, they are not compiled again.
Include files typically contain the declaration of a symbol (a function, a variable). This lets the compiler know that a name is defined (in the header) or elsewhere (in the case of a declaration):
a.h:
void a_useful_function(); //declaration
but you can also have a definition:
a.h:
void a_useful_function()
{
//... do something
}
Libraries are an accumulation of functions which get typically exposed by headers. The header is usually the interface to a library that you will be linking against.
There exist header only libraries however that have their declarations and definitions code in the same file.
You mention include directories in your question. The include directories are the places where the compiler searches to resolve an #include "a.h" preprocessor directive.
But there are also library directories where the linker searches for needed libraries that usually provide implementations (definitions) to the declarations in your headers.