#ifndef why to use an other name than the class name? - c++

Classes declarations usually look like that:
#ifndef MY_CLASS_20141116
#define MY_CLASS_20141116
...
class MyClass
{
...
}
#endif
My question is, why to not use the class name instead of redefining a new identifier:
#ifndef MyClass
...
class MyClass
{
}
#endif
I guess it has something related with identifier conflicts (a same identifier may appear twice) or the use of namespace (I do not know if a full identifier like std::array may be used in the #ifndef directive).
It would be great a more thorough explanation.
Also, it is possible to use the second test when using namespace?
#ifndef A::MyClass //not compile, any equivalent?
namespace A
{
...
class MyClass
{
}
}
#endif

First example:
#ifndef MyClass
...
class MyClass
{
}
#endif
This cannot work, because 'MyClass' is never defined for the preprocessor. All directive starting with a # are preprocessor directives and are the only ones the preprocessor understands. class MyClass has no special meaning for the preprocessor, and won't create a preprocessor definition.
For it to work, you have to define MyClass : #define MyClass.
However, by doing this, the preprocessor will replace class MyClass by class, which won't compile.
Now, second example:
#ifndef A::MyClass //not compile, any equivalent?
A::MyClass is not a preprocessor token, it is several tokens. #define SOMETHING only work with one token (which is composed of the characters a-zA-Z_0-9).

Related

Macro with a C++ class

I was going through this code (line 41):
https://github.com/black-sat/black/blob/master/src/lib/include/black/logic/parser.hpp
and came across something like this:
#include <iostream>
#define YES
class YES myClass{};
int main(){
cout << "Hi\n";
return 0;
}
What is the purpose of defining a macro and using it in front of a class identifier?
The way you've written it there isn't much point. But if you look at the project's common.hpp file to see how it's used, it makes a lot of sense, and is a common pattern in C and C++:
#ifdef _MSC_VER
#define BLACK_EXPORT __declspec(dllexport)
#else
#define BLACK_EXPORT
#endif
...
class BLACK_EXPORT parser
{
public:
...
Here the author has defined compiler-dependent attributes. If the code is built using MSVC, then any class marked with the BLACK_EXPORT macro will get the dllexport attribute. For other compilers it will do nothing.
If you see, for example:
https://en.cppreference.com/w/cpp/language/class
you'll see that there are a lot of modifiers for a class (for instance, look into the attr optional parameter here: https://en.cppreference.com/w/cpp/language/attributes).
Defining that macro with the required values can adapt the class as required whenever it is included.

C++ include a class in two header files

I have to get a project done for university but I can not figure out how it can be done.
The problem is that I want to allocate a Condition object (not a Pointer) in the GameHandler Class like in the example below, but I can not do this because I think of the included Condition.h in the Engine Class. So I am not able to include the Condition class twice. Am I wright?
What can I do to get a solution that works kind like my wrong example?
Thank you a lot!!!
Condition.h:
#ifndef CONDITION_h
#define CONDITION_h
class Condition
{
enum Rank {FIRST, SECOND, THIRD};
void doSomething();
};
#endif
Engine.h
#ifndef ENGINE_h
#define ENGINE_h
#include "Condition.h"
class Engine
{
Condition::Rank getter();
};
#endif
But now I have a third Class which should look like this where I want to create a Condition Object (not a Pointer). How can this be done?
GameHandler.h
#ifndef GAMEHANDLER_h
#define GAMEHANDLER_h
#include "Condition.h"
class GameHandler
{
Condition condition_;
condition_.doSomething();
}
#endif
By default, class members are private in C++ (more about access specifiers here). Try declaring them as public.
class Condition
{
public:
enum Rank {FIRST, SECOND, THIRD};
void doSomething();
};
Also, you cannot call a method within the declaration of a class! You'd have to do it inside a method (for example, the constructor), but the where will depend on what do you want to do.
class GameHandler
{
Condition condition_;
public:
GameHandler() {
condition_.doSomething();
}
}
Using :
#ifndef GAMEHANDLER_h
#define GAMEHANDLER_h
/.../
#endif
Will prevent multiple inclusion, so it doesn't matter if you include your header multiple times

Variadic Macros

I came across this code that involved variadic Macros and I wanted to know what that meant
#define DECLARE_LEGACY_TYPES(...) //This all of the macro - I am not holding out on anything
Now There is this class as this
Header file: .h
namespace LG_Wrapper
{
template <LG_Thread Thread>
class EffectApplication : public ktApplication
{
public:
static EffectApplication<Thread>& GetInstance();
protected:
.....
.....
static boost::recursive_mutex mResource;
}
}
DECLARE_LEGACY_TYPES(EffectApplication); <---- What does this do ?
I wanted to know what effect the macro has ?
Update:
I have received numerous downvotes on this as this question gives of the impression that something is missing that I did not post the entire content of the macro. There is nothing more to the macro. I wish there was. This question is related to this which was closed. The macro literally just ends after (...)
#define DECLARE_LEGACY_TYPES(...)
but there isnt. That is one of the reason why I am here as I am not sure how to deal with this situation. Does this macro have not effect then ?
More Info:
This is what I have in another file
I am using the following defined in my project setting
LG_WRAPPER_EXPORTS
LG_THREAD_NAME=GAME
Following is the code
namespace LG_Wrapper
{
enum LG_Thread
{
GAME,
OTHER
};
/*
If the library itself is including this file
*/
#ifdef LG_WRAPPER_EXPORTS
#ifndef LG_THREAD_NAME
#error You must define LG_THREAD_NAME!
#endif
//Legacy types should not be used internally
#define DECLARE_LEGACY_TYPES(...)
#else // LG_WRAPPER_EXPORTS
//Legacy typenames are provided for convenience to the client
#define DECLARE_LEGACY_TYPES(ClassType) \
typedef LG_Wrapper::##ClassType##<LG_Wrapper::GAME> ClassType; \
#endif // LG_WRAPPER_EXPORTS
}
This is actually pretty common, but it depends on other code that wasn't mentioned in the other code you looked at:
#if USING_OLD_COMPILER //when using an older compiler, use this to declare legacy types
#define DECLARE_LEGACY_TYPES(...) STUFF(__VA_ARGS__)
#else //new compiler doesn't have to do anything special
#define DECLARE_LEGACY_TYPES(...)
#endif
//in older compilers we had to declare legacy types for this
//newer compilers don't need this step, so this does nothing at all in them.
DECLARE_LEGACY_TYPES(EffectApplication);
I don't actually know this macro, so I don't know it's actual purpose. But it's common to see macros without definitions for similar tricks as this.

c++ Recursive headers for abstract classes

Let's say I want to compile something like this:
//Prova.h:
//--------------------
#ifndef _PROVA_
#define _PROVA_
#include "Terza.h"
class Prova{
public:
Prova();
};
#endif
and
//Terza.h:
//--------------------
#ifndef _TERZA_
#define _TERZA_
#include "EreProva.h"
class Terza{
public:
Terza();
};
#endif
and
//EreProva.h:
//--------------------
#ifndef _EREPROVA_
#define _EREPROVA_
#include "Prova.h"
class EreProva : public Prova{
public:
EreProva();
};
#endif
which doesn't compile saying "'Prova' : base class undefined".
What is the best way to avoid recursion of header between inherited classes?
If you need to have cyclic dependencies there is something wrong with your design and you should revisit your design and try to remove such complex and unwanted cyclic dependencies.
One of overcoming cyclic dependencies is to use Forward Declarations, but note that once you forward declare a type the type becomes Incomplete type for the compiler and there are limitations about what operations you can do with it. You cannot perform any operations on that type instances which need the compiler to know the memory layout of the type.
Good Read:
When can I use a forward declaration?
Sometimes you can work around problems of this sort by tring the following: (1) try adding the "#pragma once" directive at the top of your files, although this may be compiler specific (I used it when developing in VC++ some time ago) (2) instead of including the header files in the class, you can try just add "class Prova", or whatever class it is, to indicate a class which you will define later on but want to "use" now.
Although as Als says, it is better to avoid such designs.
In this code:
//Prova.h:
//--------------------
#ifndef _PROVA_
#define _PROVA_
#include "Terza.h"
class Prova{
public:
Prova();
};
Since you don't use the Tezra class in any way, you don't need the #include. Take it out. Also, you are missing and #endif. Close the #ifndef in this file with a matching #endif in this file.
Moreover:
//Terza.h:
//--------------------
#ifndef _TERZA_
#define _TERZA_
#include "EreProva.h"
class Terza{
public:
Terza();
};
#endif
#endif
You also don't use the EreProva class in this file at all -- so take out the #include statement. You also have an extra #endif at the end of the file. There is only one #ifndef here, so there should only be one #endif. Take the last one out.

Why am I getting "too many include files : depth = 1024"?

I'm using Visual Studio 2008 Express edition, and keep getting the following error:
"Cascadedisplay.h(4) : fatal error C1014: too many include files : depth = 1024.
Obviously I'm doing something very wrong with include files, but I just can't see what.
Basically, I have an interface class, StackDisplay, from which I want to derive CascadeDisplay in another file:
#if !defined __BASE_STACK_DISPLAY_H__
#define __BASE_STACK_DISPAY_H__
#include <boost\shared_ptr.hpp>
#include "CascadeDisplay.h"
namespace Sol
{
class StackDisplay
{
public:
virtual ~StackDisplay();
static boost::shared_ptr<StackDisplay>
make_cascade_display(boost::shared_ptr<int> csptr)
{
return boost::shared_ptr<StackDisplay>(new CascadeDisplay(csptr));
}
};
}
#endif
and then in CascadeDisplay.h:
#if !defined __CASCADE_DISPLAY_H__
#define __CASCADE_DISPAY_H__
#include "StackDisplay.h"
#include <boost\shared_ptr.hpp>
namespace Sol
{
class CascadeDisplay: public StackDisplay
{
public:
CascadeDisplay(boost::shared_ptr<int> csptr){};
};
}
#endif
So what's up with that?
#if !defined __CASCADE_DISPLAY_H__
#define __CASCADE_DISPAY_H__
Second line should be:
#define __CASCADE_DISPLAY_H__
Same with:
#if !defined __BASE_STACK_DISPLAY_H__
#define __BASE_STACK_DISPAY_H__
Also, names that contain a double-underscore are reserved for the implementation, you are not allowed to create such names in your own code. Same goes for names that begin with a single underscore and an uppercase letter.
There is a typo in your guards
#if !defined __CASCADE_DISPLAY_H__ <--- here you have DISPLAY
#define __CASCADE_DISPAY_H__ <--- here you have DISPAY (no L!)
and yes, avoid double underscores in such names
Is #if !defined... legit? I always used #ifndef.
Either way, why does your "base" class require the reference to CascadeDisplay? That doesn't seem right. Consider replacing your call to create a new CascadeDisplay with a call to a pure virtual function in StackDisplay that your subclass must implement appropriately.
IE, something like (and forgive, I don't have a c++ compiler handy to check this):
namespace Sol
{
class StackDisplay
{
public:
virtual ~StackDisplay();
boost::shared_ptr<StackDisplay>
make_cascade_display(boost::shared_ptr<int> csptr)
{
return make_display(csptr);
}
protected:
virtual boost::shared_ptr<StackDisplay> make_display(boost::shared_ptr<int> csptr) = 0;
};
class CascadeDisplay: public StackDisplay
{
public:
CascadeDisplay(boost::shared_ptr<int> csptr){};
protected:
virtual boost::shared_ptr<StackDisplay> make_display(boost::shared_ptr<int> csptr)
{
return new CascadeDisplay(csptr);
}
};
}
I believe this solution is superior, in general, to the forward declaration because you're eliminating some tight coupling between your superclass and your subclass, and making a more generic interface besides. This lets you eliminate the #include of CascadeDisplay.h in StackDisplay.h.