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
Related
I'm trying to create a library for a school work, and I've been wondering if it is safe to declare a templated class on the main header file containing the class definition and method declarations, but then separating the method definitions in a different header file?
Because I have been able to do this in my example below, but I don't know if it will cause me some problems in the long run.
main program
// main.cpp
#include <iostream>
#include "declaration.hpp"
int main()
{
card<int> a(5);
std::cout<<a.getID()<<'\n';
return 0;
}
main header file
in this header file, only the class definition and the declaration of the method getID() is written but not it's definition, and by the end of the class I included the other header file that contains the method definitions.
// declaration.hpp
#ifndef DEC_HPP
#define DEC_HPP
#include <iostream>
template<typename T>
class card
{
public:
T id;
card(const int id) : id(id) {}
T getID();
};
#include "definition.hpp"
#endif
method definitions
This header file contains the method definition of getID() from the main header.
I also included the "declaration.hpp" in this header, and this is the part where I'm not so sure of, because I included both files together with each other.
// definitions.hpp
#ifndef DEF_HPP
#define DEF_HPP
#include <iostream>
#include "declaration.hpp"
template<typename T>
T card<T>::getID()
{
return id;
}
#endif
I have compiled this program and it's working on my machine, but I just wanted to know if this way of isolating my code will cause me some errors in the future, I don't want to put my templated class definitions in a cpp files because I find it hard to maintain.
This is indeed a better approach because it makes your code look simple and better. Moreover, it is the main reason why header file is used.
Your main header file will simply tell that what functions/classes are you using and without even viewing your code, anyone can guess if you are working correctly or not.
There wont be any safety issues at all.
After creating and definition class (in "h file").
How do I decide to create (or not) "cpp file" (only for the class) in addition to "h file" (that belonging to the class)?
Here is a small example to get you going.
this is Foo's header file. let's call it "foo.h"
#pragma once
#ifndef FOO_H
#define FOO_H
class Foo{
public:
void function();
protected:
private:
};
#endif
This is Foo's source file. Let's call it "foo.cpp"
#include "foo.h"
void Foo::function(){
// ... implement ...
return;
}
compiling them together, we can create an object file. We'll call it "foo.o"
You can use your class in a program provided that you link "foo.o".
Example:
#include "foo.h"
int main(){
Foo foo;
foo.function();
return 0;
}
An h file is a descriptor file, that describes the signature of your functions/classes, so that other classes in other cpp files may use it.
You need to think of an h file as a contract. You are declaring an obligation.
Later on, when you decide to implement the cpp, you are fulfilling the obligation.
Other classes/cpp files can rely on your obligation alone, assuming that you will also implement the obligation in a cpp.
For example:
You create an .h file "myClassA.h" and declare a class called myClassA with a member method called myClassA.SayHello()
You include myClassA.h in another class you create myClassB.cpp, that way myClassB knows that myClassA has a method called SayHello() and it can call it.
If you do not include myClassA.h and you try to call myClassA.SayHello() inside myClassB.cpp, you'll get an error from your compiler, as myClassB does not "know" of myClassA.
If you do include the h file but did not bother to actually create and implement myClassA in myClassA.cpp, you will get a compilation error, since no implementation was found.
The best practice is to separate the header and implementation files so you define the class inside the header file .h and implement it inside the .cpp file, this will help you to trace and debugging the errors and shows a clean code ,
Just note in the templates classes it have to be defined in a separate header file to keep your code structured well and clean by separating templates from normal classes
I began to write my program in a single cpp-file but now I have too much code so I decided to separate it. But the problem is that I have many constants, includes and some other things that I want to have all in one place. Unfortunately, all of them are needed by dependent parts of code so I can't do it with usual include files.
What would help me?
(I write under Linux and compile with command-line)
(Sorry for my English :))
As Hristo said, you should generally write the definitions in header files and write the implementation in the source code files.
To answer your question however:
But the problem is that I have many constants, includes and some other things that I want to have all in one place.
What I've typically done is create a single file called something like "common.h" or "defs.h" (I took the idea from Doom...) and that file has many defines that you find you need throughout your entire program. If you are using constants, declare the constants in the header file like so:
extern const int MAX_SOMETHING;
extern const bool TRUTH_VALUE;
and make a complementary source file (defs.cpp or common.cpp) that defines these constants:
const int MAX_SOMETHING = 5;
const bool TRUTH_VALUE = true;
so now when you include the common/defs.h in other source files, the extern keyword will tell that source file that the definition is in another source file (its in the common/defs.cpp) so it will find the definition in there, and you can use it anywhere where you have included common/defs.cpp.
In most projects definitions are in header files and implementations are in source code files. However the implementations of template functions must be in the header files because they must be visible to all source files using them. Variables should be defined extern in header files and be declared in source files. Constants may also be declared in header files static.
Example:
Foo.h
#pragma once
class Foo{
public:
void bar();
template<class Type>
void increment(Type &a){
++a;
return;
}
};
extern Foo theFoo;
static const int five=5;
Foo.cpp
#include "Foo.h"
#include <iostream>
void Foo::bar(){
std::cout<<"Foo::bar called"<<std::endl;
return;
}
Foo theFoo;
Main.cpp
#include "Foo.h"
#include <iostream>
int main(){
theFoo.bar();
std::cout<<five<<std::endl;
return 0;
}
I have two .cpp files in one project, main.cpp and myfile.cpp
I have globaly defined struct mystruct in main.cpp, now I want to use this struct in myfile.cpp.
When I write mystruct in a header file and include in both cpp files I get an error, saying mystruct redefinition. How should I solve this problem.
If you are trying to share the definition of a struct among several compilation units (cpp files), the common way is this: Place the definition of your struct in a header file (mystruct.h). If the struct contains any methods (i.e. it is rather a class with all member public by default), you can implement them in mystruct.CPP file, or, if they're lightweight, directly within the struct (which makes them inline by default).
mystruct.h:
#ifndef MYSTRUCT_H
#define MYSTRUCT_H
struct MyStruct
{
int x;
void f1() { /* Implementation here. */ }
void f2(); /* Implemented in mystruct.cpp */
};
#endif
mystruct.cpp
#include "mystruct.h"
// Implementation of f2() goes here
void MyStruct::f2() { ... }
You can use your struct in as many cpp files as you like, simply #include mystruct.h:
main.cpp
#include "mystruct.h"
int main()
{
MyStruct myStruct;
myStruct.x = 1;
myStruct.f2();
// etc...
}
If, on the other hand, you are trying to share a global instance of the struct across several compilation units (it's not absolutely clear from your question), do as above but also add
extern MyStruct globalStruct;
to mystruct.h. This will announce that an instance is available with external linkage; in other words that a variable exists but is initialized elsewhere (in your case in mystruct.cpp). Add the initialization of the global instance to mystruct.cpp:
MyStruct globalStruct;
This is important. Without manually creating an instance of globalStruct, you'd get unresolved-external linker errors. Now you have access to globalStruct from each compilation unit that includes mystruct.h.
You should move the common struct to a header file and include that header in both files. Any other solution is a workaround.
The problem is that you basically have the same code twice as a result if you see an include as just a import of the code.
You can use #ifdef to fix it, see http://www.fredosaurus.com/notes-cpp/preprocessor/ifdef.html
Declaration and definitions are two different things. For your case, you are allocating space for your structure in main.cpp. In your header, you should use the extern modifier for your struct so that all files that include the header file will look in the global namespace for the structure. Hope it helps.
The standard C/C++ approach:
// source.h
Put all struct, class, typedef, macro definitions, extern variable declaraltions
// source.cpp
Implement the class, functions, define global/external variables
// main.cpp, and other parts of program
#include"source.h"
You should define structure in the header file only, you should remove definition from main.cpp
May be you can give more information about what is the layout of your project.
Going by the guess, probably your problem can be either of the two:
you want forward declaration of struct.
using include guards to prevent redefinition.
See the following link for how to handle both:
http://www.adp-gmbh.ch/cpp/forward_decl.html
The header files also use include guards, so you can figure out what exactly can solve your problem.
If you want to share any variable between multiple cpp files, you should declare it in header as extern. And without extern in one of that c++ files.
If you don't do it, it'll lack at linking, because multiple objects would have variable with same name. Instead when using extern one object would have this variable and other objects link it.
The header is where you declare what your struct will consist of (probably a common.h file included by main.cpp and myfile.cpp):
struct MyStruct {
int messageID;
int tempVariable;
};
In your main.cpp, this is where you actually use the struct:
void someFunction() {
struct MyStruct tempStruct;
// do something with it
tempStruct.messageID = 1;
}
Don't put the definition of your struct in both your main.h and main.cpp - or you will get a redefinition error!
Also, don't include the cpp file - include the header file (e.g. common.h). Without knowing more about the structure of your program, it is hard to provide better information.
What are the advantages of having declarations in a .inl file? When would I need to use the same?
.inl files are never mandatory and have no special significance to the compiler. It's just a way of structuring your code that provides a hint to the humans that might read it.
I use .inl files in two cases:
For definitions of inline functions.
For definitions of function templates.
In both cases, I put the declarations of the functions in a header file, which is included by other files, then I #include the .inl file at the bottom of the header file.
I like it because it separates the interface from the implementation and makes the header file a little easier to read. If you care about the implementation details, you can open the .inl file and read it. If you don't, you don't have to.
Nick Meyer is right: The compiler doesn't care about the extension of the file you're including, so things like ".h", ".hpp", ".hxx", ".hh", ".inl", ".inc", etc. are a simple convention, to make it clear what the files is supposed to contain.
The best example is the STL header files which have no extension whatsoever.
Usually, ".inl" files do contain inline code (hence the ".inl" extension).
Those files ".inl" files are a necessity when you have a dependency cycle between header code.
For example:
// A.hpp
struct A
{
void doSomethingElse()
{
// Etc.
}
void doSomething(B & b)
{
b.doSomethingElse() ;
}
} ;
And:
// B.hpp
struct B
{
void doSomethingElse()
{
// Etc.
}
void doSomething(A & a)
{
a.doSomethingElse() ;
}
} ;
There's no way you'll have it compile, including using forward declaration.
The solution is then to break down definition and implementation into two kind of header files:
hpp for header declaration/definition
inl for header implementation
Which breaks down into the following example:
// A.hpp
struct B ;
struct A
{
void doSomethingElse() ;
void doSomething(B & b) ;
} ;
And:
// A.inl
#include <A.hpp>
#include <B.hpp>
inline void A::doSomethingElse()
{
// Etc.
}
inline void A::doSomething(B & b)
{
b.doSomethingElse() ;
}
And:
// B.hpp
struct A ;
struct B
{
void doSomethingElse() ;
void doSomething(A & a) ;
} ;
And:
// B.INL
#include <B.hpp>
#include <A.hpp>
inline void B::doSomethingElse()
{
// Etc.
}
inline void B::doSomething(A & a)
{
a.doSomethingElse() ;
}
This way, you can include whatever ".inl" file you need in your own source, and it will work.
Again, the suffix names of included files are not really important, only their uses.
Since nobody else has mentioned it:
The use of .inl files to store your inline functions can be useful for speeding up compiles.
If you only include the declarations (.h) where you need declarations, and only include inline implementations (.inl) where you need them ( i.e. probably only in .cpp and other .inl files, not .h's ), it can have a beneficial effect on your header dependencies.
This can be a significant win on larger projects with many interacting classes.
In my experience, .inl files are used to define inline functions. When they're in an .inl file, the file can be included in a header to get inline functions and in a .c file to get regular function definitions.
This way the same source can more easily work with compilers that do not have inline function supportas well as compilers that do.
They're usually used with straight C code, not often with C++ code as all C++ compilers support inline functions.
I believe it's just a naming convention for a "header" file includes inline code.
it's so that .h files can contain definitions and .inl files contain inline code which is necessary for templates.
I don't belive there is anything more to it than an naming convention to make the purpose of the file clear