headerfile inclusion in pure virtual classes - c++

If I have a pure virtual class like the following:
I have class structure like the following:
class interface_class {
virtual void someFunction(MyClassA& a) = 0;
virtual void someFunction(MyClassB& b) = 0;
}
What is the correct way to include MyClassA/MyClassB? Should I do some forward declaration in the header file of the interface class and do the real inclusion in the header file of the implemention, or should I include the header file of MyClassA/B directly in the interface class?

Use Forward Declarations for both the classes.
In fact always use forward declarations wherever you can.
Using forward declarations saves you compilation time & also restricts you from creating unneeded dependencies.

You should use a forward declaration in a separate header file.
That is you have your current header files with the definition of MyClassA and MyClassB. You'll need to group classes used at the same time and create a new header file like this:
file MyClassesFwd.h (naming convention up to you)
namespace XX {
class MyClassA;
class MyClassB;
}
Your interface header:
#include <MyClassesFwd.h>
// ... your interface definition ...
An actual source file will look like this on the other hand:
#include <MyClassA.h>
#include <MyClassB.h>
#include <MyInterface.h>
This will prevent you from rewriting the forward declaration everytime.

Related

Is it safe to separate your templated class' declaration and definitions on different header files?

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.

Preventing "already defined" error for class implementation in header file

I want to include the definition and implementation of a C++ class in a header file.
I'm creating a library that need to be C-compatible. The .h file defines a C++ class that can be subclassed for easy C++-style access to the library. It is internally used in the library as well.
As the header file is imported into several subclasses, I always get the "multiple definition" error. Because the class definition should be importable for users of the library, I do not want to move the implementation in a separate cpp file.
Do you have any idea how this problem can be solved?
simplified example:
//library:
typedef struct IFoo{
virtual void foo = 0;
};
void library_fun_a(IFoo*);
void library_fun_b(IFoo*);
//header file
#pragma once
class FooWrapper : public IFoo{
virtual void foo() override;
};
void FooWrapper::foo(){
//some magic here
}
[Edit] Using include guards doesn't help to stop the compile from including the implementation in all object files and therefore the linker to encounter the "multiple definition" error.
You must use include guards which are essentially just macros that determine if the compiler has already included the interface or whatever contents are in the header file.
For example
#ifndef FOO_WRAPPER_H
#define FOO_WRAPPER_H
// header contents here ...
#endif // !FOO_WRAPPER_H
If you're using a Microsoft compiler, you can use the directive #pragma once at the top of the header file. Note that this breaks compatibility with other compilers.
You can easily solve your multiple defintion problem when you inline your code correctly:
class FooWrapper : public IFoo {
virtual void foo() override {
//some magic here
}
};

forward declaration and cyclic header inclusion in C++

I have two classes
RequestManager.h
#ifndef REQUESTMANAGER_H
#define REQUESTMANAGER_H
#include "RequestClient.h"
class RequestManager
{
public:
void AddReqeustItem(RequestClient *req);
private:
std::list<RequestClient*> m_reqClientContainer;
};
#endif
RequestClient.h
#ifndef REQUESTCLIENT_H
#define REQUESTCLIENT_H
class RequestManager; // Forward declaration to avoid cyclic inclusion.
class RequestClient {
public:
void CreateRequest(RequestManager* pManager)
{
// ... I am creating a request.
pManager->AddReqeustItem(req);
};
#endif
In the code above I am getting error undefined RequestManager in Request client class. What is the problem and how can I solve it?
You cannot use a type with only a forward declaration. Forward declaration are used to say to compiler that type exists but compiler does not know the content of the type.
My advice:
In header file, I would only define class and function members. So forward declaration is possible if only pointer are used.
In body file, write the code your member function and include the header files
put the member function definition in a source file which #includes both headers.
Or, if you still want it to be inline (or if it's templated), then put the definition of the member function body further in the header, after all relevant code is defined. In the case of a single header file (which does make sense here):
class B; // forward decl
class A {
void use(B*);
};
class B {
void use(A*);
};
void A::use(B*b) { /* ... */ }
void B::use(A*a) { /* ... */ }
Note the splitting of the code into files (several headers and one source) is only a convenience for the programmer (making it much simpler to maintain and use by other parts of the code), but from the point of view of the compiler this doesn't matter: it sees only one big file of code (after pre-processing). So, it's up to you how you split the above layout into headers and source file.
You use the method RequestManager::AddReqeustItem(), but there's only a forward declaration of RequestManager. With just a forward declaration the compiler doesn't even know which methods of RequestManager exist. So, to fix this problem, you must provide the definition of RequestManager, which is usually in the header file.
Move the method definition of CreateRequest() into the cpp file and include RequestManager.h there
RequestManager.cpp:
#include "RequestManager.h"
...
void CreateRequest(RequestManager* pManager)
{
// ... I am creating a request.
pManger->AddReqeustItem( req);
}

class (cpp file & h file) in c++

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

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