The common practice in C++ is to separate declarations in .h
(or .hpp
) and implementation into .cpp
.
I know about two main reasons ( maybe there are others ):
- Compilations speed ( you do not have to recomplie everything when you change just one file, you can link it by
make
from pre-compiled.o
files ) - Forward declarations are sometimes necessary ( when implementation of
class A
depends onclass B
and implementation ofclass B
onclass A
) ... but I don't have this problem so often and usulaly I can solve it.
In case of object oriented programming it looks like this:
QuadraticFunction.h
:
class QuadraticFunc{
public:
double a,b,c;
double eval ( double x );
double solve( double y, double &x1, double &x2 );
};
QuadraticFunction.cpp
:
#include <math.h>
#include "QuadraticFunc.h"
double QuadraticFunc::eval ( double x ){ return c + x * (b + x * a ); };
double QuadraticFunc::solve( double y, double &x1, double &x2 ){
double c_ = c - y;
double D2 = b * b - 4 * a * c_;
if( D2 > 0 ){
double D = sqrt( D2 );
double frac = 0.5/a;
x1 = (-b-D)*frac;
x2 = (-b+D)*frac;
}else{ x1 = NAN; x2 = NAN; }
};
main.cpp
:
#include <math.h>
#include <stdio.h>
#include "QuadraticFunc.h"
QuadraticFunc * myFunc;
int main( int argc, char* args[] ){
myFunc = new QuadraticFunc();
myFunc->a = 1.0d; myFunc->b = -1.0d; myFunc->c = -1.0d;
double x1,x2;
myFunc->solve( 10.0d, x1, x2 );
printf( "soulution %20.10f %20.10f \n", x1, x2 );
double y1,y2;
y1 = myFunc->eval( x1 );
y2 = myFunc->eval( x2 );
printf( "check %20.10f %20.10f \n", y1, y2 );
delete myFunc;
}
then compile it with makefile
like this:
FLAGS = -std=c++11 -Og -g -w
SRCS = QuadraticFunc.cpp main.cpp
OBJS = $(subst .cpp,.o,$(SRCS))
all: $(OBJS)
g++ $(OBJS) $(LFLAGS) -o program.x
main.o: main.cpp QuadraticFunc.h
g++ $(LFLAGS) -c main.cpp
QuadraticFunc.o: QuadraticFunc.cpp QuadraticFunc.h
g++ $(LFLAGS) -c QuadraticFunc.cpp
clean:
rm -f *.o *.x
However, I find it often very inconvenient
especially, when you change code a lot ( e.g. in initial phase of development when you are not yet sure about overall structure of the whole project ).
- You have to go back-and-forth all the time between
.cpp
and.h
part of code when doing significant changes to the class structure. - You have twice as much files in the editor and in project folder which is confusing.
- You have to write some informations ( like function headers or
QuadraticFunc::
) twice, where you can do many typos and inconsistencies so the compiler complains all the time ( I do such mistakes very often ) - Every-time you add / remove / rename some class you have to edit
Makefile
, where you do a lot of other mistakes which are hard to track from the compiler output ( e.g. I often forgot to write Makefile so that the code recompiles every dependency which I edit )
From this point of view I like much more how Java works. For this reason I was writing my C++ programs simply by putting all the code (including implementation) inside .h
. Like this:
#include <math.h>
class QuadraticFunc{
public:
double a,b,c;
double eval ( double x ){ return c + x * (b + x * a ); }
double solve( double y, double &x1, double &x2 ){
double c_ = c - y;
double D2 = b * b - 4 * a * c_;
if( D2 > 0 ){
double D = sqrt( D2 );
double frac = 0.5/a;
x1 = (-b-D)*frac;
x2 = (-b+D)*frac;
}else{ x1 = NAN; x2 = NAN; }
};
};
with universal default makefile like this:
FLAGS = -std=c++11 -Og -g -w
all : $(OBJS)
g++ main.cpp $(LFLAGS) -w -o program.x
( main.cpp
remains the same )
However, now when I'm starting to write more complex programs, the compile time starts to be quite long when I have to recompile everything all the time.
Is there any way how to use advantages of make
( faster compile time ) and still organize program structure in the Java-like way ( everything in class body instead of separate .h
and .cpp
) which I find much more convenient ?