I've started a C++ project, and for the first time I'm trying to write in OOP style.
Before this, my programming style was just to cut-and-paste functions from the .cpp files out into .h files. This way I kept common code in header files.
However now I'm trying to do OOP style programming, while reusing my "helper" .h files. Those files have very little code, for example some interpolation or number formatting.
Here is where I'm confused. I've gone quite far, but now I'm in a point where I'd like to include a header-only helper function file I've made before. The problem is that if I include it in a class, it works, but then I cannot include it in another class.
The error message I receive is
error LNK2005: "float __cdecl calculateZ(int)" (?calculateZ@@YAMH@Z) already defined in Fruit.obj
I've tried putting pragma once before all header files but it didn't help. But why did it happen only for my header-only file, while lot of other header files are included more then once?
Other than solving this problem what do you recommend as a general OOP style programming for header files? For small projects with a few classes, wouldn't it be better to include everything in a common header file and just include a "common.h" in all class? If yes, could you recommend me a solution what would simply put all required includes in one header file? I mean one #include "common.h" on top of each other file. Is this method bad?
I'm asking this question because I find that I spend way more time figuring out what include goes before what header files. Before, when I wasn't doing OOP style programming these things have never existed. Where can I learn how to manage these includes in a clean way?
Here is the code for the project (bodies deleted):
simulatorApp.cpp
#include "cinder/app/AppBasic.h"
#include "../include/FruitManager.h"
#include "cinder/gl/gl.h"
#include "cinder/gl/Texture.h"
#include "cinder/Vector.h"
#include "cinder/ImageIO.h"
#include "cinder/Utilities.h"
#include "cinder/params/Params.h"
#include "cinder/Camera.h"
#include "cinder/Rand.h"
//#include "../include/helper.h" // <- including this breakes the code, as it's already included below
#include "../include/showWin32Console.h"
using namespace ci;
using namespace ci::app;
using namespace std;
... function body
FruitManager.cpp
#include "../include/FruitManager.h"
#include "cinder/Vector.h"
#include <boost/algorithm/string.hpp>
... function body
Fruit.cpp
#include "../include/Fruit.h"
#include "../include/helper.h" // <- included here first
#include "cinder/Vector.h"
#include <boost/algorithm/string.hpp>
... function body
FruitManager.h
#pragma once
#include "cinder/app/AppBasic.h"
#include "Fruit.h"
#include <list>
using namespace ci;
using namespace ci::app;
using namespace std;
class FruitManager
{
public:
FruitManager();
void readFruitDimensions();
void readFruitScripLine( string line );
void addFruitsFromScriptFile( string scriptfile );
void draw();
struct boundingBox
{
Vec3f subvolmin;
Vec3f subvolmax;
};
map<string, boundingBox> FruitDimensions;
list<Fruit> FruitList;
};
Fruit.h
#pragma once
#include "cinder/app/AppBasic.h"
using namespace ci;
using namespace ci::app;
using namespace std;
class Fruit
{
public:
Fruit();
void draw();
string fruit_name;
Vec3f subvolmin;
Vec3f subvolmax;
Vec2f positionXY;
};
showWin32Console.h
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <iostream>
#include <string>
void showWin32Console()
{
... function body
}
helper.h (problematic)
#pragma once
string numformat( double num, int left, int right )
{
... function body
}
float quadraticBezier( float x, float a, float b )
{
... function body
}
float scaleFun( float f, float f0, float f1 )
{
... function body
}
float calculateZ( int framenumber )
{
... function body
}