forward declaration and cyclic header inclusion in C++ - 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);
}

Related

Is it possible to add an include directive inside of a class definition?

I am currently working on a project where we have a shared set of headers. Now we want add some private fields without having to put those declarations directly in the shared headers.
Someone brought up the following:
namespace something {
class Foo {
public:
Foo();
void doFoo();
private:
#if __has_include("foo_private.hpp")
#include "foo_private.hpp"
#endif
};
}
Inside the _private.hpp headers we would then place the private fields for that class. When there are only default datatypes (int, bool, etc) this works fine(ish). But as soon as you put an include inside the _private.hpp file, for example #include everything breaks.
It is giving the following error expected unqualified-id before ‘namespace’ which as I understand is quite logical, since you're trying to define a namespace inside of a class.
Example _private.hpp file
#ifndef DUMMY_PRIVATE_TEMPLATE_INCLUDES_FOO_PRIVATE_HPP
#define DUMMY_PRIVATE_TEMPLATE_INCLUDES_FOO_PRIVATE_HPP
#include <string>
int mySecretNumber;
std::string mySecretString;
#endif
Now my question is, is there any way to trick the preprocessor, or somehow get the same results with a different solution?
namespace something {
class Foo {
public:
Foo();
void doFoo();
private:
#if __has_include("foo_private.hpp")
#include "foo_private.hpp"
#endif
};
}
If that code is including a file that looks like this:
#ifndef DUMMY_PRIVATE_TEMPLATE_INCLUDES_FOO_PRIVATE_HPP
#define DUMMY_PRIVATE_TEMPLATE_INCLUDES_FOO_PRIVATE_HPP
#include <string>
int mySecretNumber;
std::string mySecretString;
#endif
Then you end up with this (though in reality, the #includes themselves would resolve to the contents of <string>, etc.):
namespace something {
class Foo {
public:
Foo();
void doFoo();
private:
#ifndef DUMMY_PRIVATE_TEMPLATE_INCLUDES_FOO_PRIVATE_HPP
#define DUMMY_PRIVATE_TEMPLATE_INCLUDES_FOO_PRIVATE_HPP
#include <string>
int mySecretNumber;
std::string mySecretString;
#endif
};
}
Perhaps that shows your issue? You're including "string" in the middle of your class, but it needs to be included at the global namespace scope of your file.
Instead, include string at the top of the outer header, don't use include guards in the private header, and only put the body of the code you want pasted into your class into that private header. For that reason, you might not call it a ".hpp" file but something else to make it clear it's not a normal header.
Additionally, the __has_include feature seems dubious, because if your private header is missing you probably do not want it to compile to an empty class.
Worse, if you compile some translation unit that finds the header, and then compile another translation unit that does not find the private header, you will end up with two different definitions of your class, violating the One Definition Rule -- which is undefined behavior, no diagnostic required. Really nasty stuff (assuming your builds succeeds at all.)
I'm not a big fan of this kind of hiding, as it will make it hard for editors to properly show your code, to colorize and index your private header, or otherwise work with the code in a normal way. You might consider looking at the PIMPL idiom for hiding the implementation of a class in its .cpp file, so users of the header do not have to see it 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
}
};

multiple definition in stl class header

I am getting stuck using this class, when I used in the main.cpp there is no problem and execute perfectly, but when I use it as a member class the compiler doesn't like it and sends the message "Multiple definition of:"
Here is the class:
RTPSocket.h:
#ifndef RTP_SOCKET_HDR
#define RTP_SOCKET_HDR
namespace RTPConnection
{
enum EMode
{
Sender,
Receiver
};
template<EMode Mode>
class RTPSocket
{
};
}//end namespace
#define RTP_SOCKET_IMP
#include "RTPSocket_Imp.h"//file where i declare the implementation code
#undef RTP_SOCKET_IMP
#endif
this class by itself doesn't have any problem but when i use it in my class, but ....
used in another class
my file.h
#include RTPSocket.h
class CommClass
{
private:
RTPSocket<RTPConnection::Receiver> * mRTPServer;
}
the compiler give this error message:
multiple definition of 'enum RTPConnection::EMode'
this is a method that is declared in another file "rtpsocket_imp.h"
with the guard declared:
template<EMode Mode>
void RTPSocket<Mode>::write(char* aArray,
const size_t aiSize)
{
std::string message("The write function is operative only on Sender Mode");
throw BadTemplate(message);
}
You want include guards around the header:
#ifndef RTPSOCKET_H
#define RTPSOCKET_H
// header contents go here
#endif
This will prevent the header contents from being included more than once per source file, so you will not accidentally get multiple definitions.
UPDATE: Since you say you have include guards, then possible causes of the error might be:
misspelling the include guard name, so it doesn't work
defining something with the same name in another header (or the source file that includes it)
undefining the include guard name.
But without seeing code that reproduces the error, I can only guess what might be wrong.
You need an include guard.
Inside the RTPSocket.h file at the top put
#ifndef RTPSOCKET_INCLUDED
#define RTPSOCKET_INCLUDED
and at the end put
#endif
If that's not the problem, and you do have an include guard, I suggest you search for
enum EMode
in your code and find all the places you have defined it, and make sure you just define it once.
My problem was the CMakeLists.txt that was building this project.
My fault!

headerfile inclusion in pure virtual classes

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.

When are includes not needed?

I admit I'm a bit naive when it comes to includes. My understanding is that if you use it in your class you either need to include it or forward declare it. But then I was going through some code and I saw this:
// file: A.cpp
#include "Helper.h"
#include "B.h"
#include "C.h"
#include "A.h"
// ...
// file: A.h
B b;
C c;
// ...
// file: B.h
Helper h;
// ...
// file: C.h
Helper h;
// ...
Can someone explain to me why B and C does not need to include Helper? Also, what are the advantages/disadvantages to organizing includes this way? (Besides the obvious less typing.)
Thanks.
When you #include some header (or other) file into a .cpp file, that #include statement is simply replaced by the content of the header file. For example:
//header.h
int i;
float f;
// file.cpp
#include"header.h"
int main()
{}
After preprocessing stage, file.cpp will look like,
int i;
float f;
int main()
{}
Can see this in g++ using g++ -E file.cpp > TEMP, which shows you just the preprocessed files.
In your present question context, you must have #include helper.h in/before B.h and C.h as they appear before and you declare an object of those types.
Also, it's not good practice to rely on the arrangement of header files to get the code working, because once you alter arrangement little, the whole hierarchy collapses with several compilation errors.
Instead #include everything in the file if you are using it and you can use the #ifndef guards to avoid multiple inclusion:
//helper.h
#ifndef HELPER_H
#define HELPER_H
// content of helper file
#endif
If the class definitions for B and C don't actually refer to any of the members of the Helper class, then the compiler doesn't need to see the full definition of the Helper class in their header files. A forward declaration of the Helper class is sufficient.
For example, if the definition of the B class only uses pointers or references to Helper, then a forward reference is recommended :
class Helper;
class B {
// <SNIP>
Helper* helper;
// <SNIP>
void help(const Helper& helper);
// <SNIP>
};
If the definition of the B class uses an instance of the Helper class (ie. it needs to know the size of the Helper instance), or otherwise refers to the definition of the Helper class (in template functions eg.), then you need to make the full definition of the Helper class visible (most likely by including the header file that defines the Helper class) :
#include "helper.h"
class B {
// <SNIP>
Helper helper;
// <SNIP>
void help(Helper helper);
// <SNIP>
};
The rule of when to use includes versus forward declarations is relatively straightforward : use forward declarations when you can, and includes when you have to.
The advantage of this is clear : the less includes you have, the less dependencies there are between header files (and the more you'll speed up compilation).
Think of #include as literally including the text of the other file in this one - it's exactly the same as if you had copied it in. So in this case, the reason B and C don't need to include Helper is because you've included it in the same "compilation unit", which is what the combination of a .cpp file and all its includes is called.
With templates, a forward declaration might be enough even if the members of the forward declared type are referred to in the header file.
For example, the boost::shared_ptr<T> implementation only forward declares boost::weak_ptr<T> even though it is used in two constructors. Here is a code snipped from http://www.boost.org/doc/libs/1_47_0/boost/smart_ptr/shared_ptr.hpp:
namespace boost
{
// ...
template<class T> class weak_ptr;
// ...
template<class T> class shared_ptr
{
// ...
public:
// ...
template<class Y>
explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn) // may throw
{
// it is now safe to copy r.px, as pn(r.pn) did not throw
px = r.px;
}
template<class Y>
shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag ): px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) // never throws
{
if( !pn.empty() )
{
px = r.px;
}
}
In this case, a forward declaration of boost::weak_ptr<T> is enough since the two constructors do not get instantiated unless the definition for the forward declared boost::weak_ptr<T> has been included in the compilation unit that is using those constructors.