First the basics. Never define a function
* in a header file. Your functions.h file does. Function declarations go in a header file, but definitions go in a source file. When you are working on a program with a single .cpp file, it doesn't matter, but eventually you will start working on larger programs with multiple source files and you will start running into link errors.
* Exceptions: inline function definitions should usually be in a header file. Template function definitions (which technically aren't functions) should be in a header file. You'll learn about these when you get more experience.
My goal is...
1. Having a layout where most include files are specified only in one place |
I'm not sure what you mean. Do you mean having a master header file (like header.h)?
This is counterproductive. For your sample program with 1 or 2 source files, this is fine, but when you start working on projects with hundreds or thousands of files that take minutes or hours to compile, this strategy will come back to bite you. A change to a single header file will cause the entire project to be rebuilt when only a handful of files are really affected. Learning how to do it the correct way now will save you tons of headache down the road.
2.Having my functions and structs in individual files
|
Usually, each class (or struct in your example) will have one header file and one source file. It is bad practice to define more than 1 class (struct) in a header file unless they are closely coupled (intimately related) to each other. If I have a source file that needs class A but not class B, I don't want to pull in a header that defines both.
I read that you usually only have one header file and the rest cpp. |
I think you misunderstood the context of that statement (or else the writer is off his rocker). For a class, 1 header and the rest .cpp. For a project, many header files and many .cpp files.
A more robust file breakdown would be as such:
functions.h
1 2 3 4 5 6 7
|
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
void test1();
void test2();
#endif
|
A.h
1 2 3 4 5 6 7 8 9 10 11 12 13
|
#ifndef A_H
#define A_H
struct A {
int a = 2;
int b;
A() {
int b = 4;
}
};
#endif
|
B.h
1 2 3 4 5 6 7 8
|
#ifndef B_H
#define B_H
struct B {
int z = 22;
};
#endif
|
MyMap.h
1 2 3 4 5 6 7 8 9
|
#ifndef MYMAP_H
#define MYMAP_H
#include "A.h"
#include <map>
namespace S {
using MyMap = std::map<int, A>;
}
|
functions.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
#include "functions.h"
#include <iostream>
void test1() {
test2();
}
void test2() {
std::cout << "yo" << std::endl;
}
|
project.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13
|
#include "A.h"
#include "B.h"
#include "ByMap.h"
#include "functions.h"
int main() {
S::MyMap theMap;
A a;
B b;
test1();
}
|