I'm trying to build a solution which has three files. With main.cpp it is four files.
Entity.h
#pragma once
#include "SystemBase.h"
namespace Engine {
class Entity {
public:
Entity() { }
void s(SystemBase* sb) { }
};
}
SubscribersList.h
#pragma once
#include "SystemBase.h"
#include "Entity.h"
namespace Engine {
class SubscribersList {
friend SystemBase;
public:
SubscribersList() { }
void f(Entity* e) { }
};
}
SystemBase.h
#pragma once
#include "SubscribersList.h"
#include "Entity.h"
namespace Engine {
class SystemBase {
public:
SystemBase() { }
void g(Entity* e) { }
private:
SubscribersList m;
};
}
Don't focus on the body's of methods in the headers. It is just to keep things simple. I found two ways to build the solution.
1. Write the word class before all class names. But it crashes when I try to separate the realization from prototypes.
2. Write all code in one file.
I don't/won't write the keyword class before all class names to build the solution, and certainly I don't/won't write a big project in one file. So why I can't build it? What is the magic?!
To understand the problem of cyclic header dependency we first need understand the difference between a class declaration and definition and the concept of incomplete types.
A prototype or forward declaration of a type Type is written as:
class Type;
Such a forward declaration allows you to create pointers and reference to that type.
You cannot however instantiate, dereference pointers to or use a reference to Type until its full type is declared.
A declaration for Type could be written as:
class AnotherType;
class Type {
public:
void aMemberFunc();
private:
AnotherType *m_theOtherThing;
};
Now we have the declaration instances can be created and pointers to Type can be dereferenced.
However before m_theOtherThing is dereferenced or instanciated AnotherType must be fully declared.
class AnotherType {
Type m_aType;
}
Should do, which gives us both the full declaration and definition of AnotherType.
That allows to continue on to write the definition of Type::aMemberFunc:
void Type::aMemberFunc() {
m_theOtherThing = new AnotherType();
}
If instead of presenting this code to the compiler in this order we instead presented the full declarations of Type and AnotherType up front:
class Type {
public:
void aMemberFunc();
private:
AnotherType *m_theOtherThing;
};
class AnotherType {
Type m_aType;
}
Then AnotherType *m_theOtherThing; will fail to compile as AnotherType has not been declared or forward declared by that point.
Switching the order gives:
class AnotherType {
Type m_aType;
}
class Type {
public:
void aMemberFunc();
private:
AnotherType *m_theOtherThing;
};
Now Type m_aType; will not compile as Type has not been declared. A forward declaration would not do in this case.
Using #pragma once instead of header guards does not in anyway change the problem. #pragma once only ensures the header is include just once it does not effect the order the compiler processes the code otherwise. It certainly does not allow the compiler to ignore undefined types when it reaches them.
For this kind of class structure there is no way for the compiler to be able to process it without the use for forward declarations.
Related
I've got two classes, Entity and Level. Both need to access methods of one another. Therefore, using #include, the issue of circular dependencies arises. Therefore to avoid this, I attempted to forward declare Level in Entity.h:
class Level { };
However, as Entity needs access to methods in Level, it cannot access such methods, since it does not know they exist. Is there a way to resolve this without re-declaring the majority of Level in Entity?
A proper forward declaration is simply:
class Level;
Note the lack of curly braces. This tells the compiler that there's a class named Level, but nothing about the contents of it. You can then use pointers (Level *) and references (Level &) to this undefined class freely.
Note that you cannot directly instantiate Level since the compiler needs to know the class's size to create variables.
class Level;
class Entity
{
Level &level; // legal
Level level; // illegal
};
To be able to use Level in Entity's methods, you should ideally define Level's methods in a separate .cpp file and only declare them in the header. Separating declarations from definitions is a C++ best practice.
// entity.h
class Level;
class Entity
{
void changeLevel(Level &);
};
// entity.cpp
#include "level.h"
#include "entity.h"
void Entity::changeLevel(Level &level)
{
level.loadEntity(*this);
}
you two options:
use pointers in which case your forward declares should be ok.
inline the methods of one class, in which case if you include the .h file you can use the methods of the other.
Personally I would go down path number 1, it's cleaner and allows better access. I use a lot of shared_ptr so I do not have to worry about deletes...
Entity.h:
class Level;
class Entity {
private:
Level* m_pLevel;
public:
bool CheckLevel ();
bool WasItThere();
Level.h
class Entity;
class Level {
private:
Entity* m_pEntity;
public:
public bool CheckMyStuff();
public bool CheckItOut() { return m_pEntity->WasItThere();}
}
Entity.cpp
#include "Level.h"
bool Entity::CheckLevel () {
return true;
}
bool Entity::CheckLevel() {
return m_pLevel->CheckMyStuff();
}
bool Entity::WasItThere() {
return true;
}
Level.cpp
bool Level::CheckMyStuff() {
return true;
}
bool Level::CheckItOut() {
return m_pEntity->WasItThere();
}
In my class I have the need to keep a pointer to a structure which is defined in a library I use to implement it. Since this library is only used within the implementation file I would like to avoid including it in the header directly. At the same time I want to avoid polluting the namespace. Thus I would like to do:
/* HEADER */
class Foo {
private:
struct ImplementationDetail;
ImplementationDetail * p;
};
/* SOURCE */
#include <Library.h>
using Foo::ImplementationDetail = Library::SomeStruct;
But this doesn't work, and I'm currently falling back on PIMPL:
/* HEADER */
class Foo {
private:
struct ImplementationDetail;
ImplementationDetail * p_;
};
/* SOURCE */
#include <Library.h>
struct ImplementationDetail {
Library::SomeStruct * realp_;
}
Is there a way to avoid the double dereference? Is the reason for my non-working first solution due to unknown pointer sizes?
// Header
class Foo {
private:
struct ImplementationDetail;
ImplementationDetail * p;
};
// Source
#include <Library.h>
struct Foo::ImplementationDetail :public Library::SomeStruct {
// ....
};
and allocating/deallocating/dereferencing the pointer in this source file only should work just fine.
This is an incorrect declaration:
using Foo::ImplementationDetail = Library::SomeStruct;
using doesn't work this way. In C++11 using cannot create an alias for a name in one namespace to a name in another namespace. In C++03, all using does is bring some other namespace in to global visibility in the current translation unit. It's not used to create aliases in C++03, as you seem to want to do here.
pimpl is the de-facto method for doing what you're trying to do, but in your header file instead of trying to use a ImplementationDetail*, I would use a simple void*. Using a void* in this manner is guaranteed to be correct according to the Standard:
class Foo {
private:
void * pImpl;
Use static_cast2 to go from a void* to your actual type:
void Foo::Bar()
{
Library::SomeStruct* thingy = static_cast <Library::SomeStruct*> (pImpl);
// ...
}
You can avoid using the void* in a conformant way by forward-declaring your library type:
namespace Library
{
struct SomeStruct;
};
class Foo
{
private:
Library::SomeStruct* pStruct;
};
And then no ugly cast is needed in the implementation.
2 Use static_cast : Or reinterpret_cast
The reason you can't take your first approach is that in the header you tell the compiler "I'm declaring a nested class within Foo and it's called ImplementationDetail". Then you proceed to say "wait wait, it's NOT a new class, it's an alias to this other thing entirely" and understandably the compiler gets confused.
Have you tried just forward declaring the library's implementation and using that instead of trying to create an alias?
In your first code you declared the nested type ImplementationDetail to be a struct which will be define inside Foo. Trying to alias it can't work because that would be a type defined elsewhere and, actually, you private structure isn't accessible from outside the class. Wrapping a pointer to another object inside seems unecessary: you could instead either embed the Library::SomeStruct by value or have your ImplementationDetail derive from Library::SomeStruct:
struct ImplementationDetail
: Library::SomeStruct {
using Library::SomeStruct::SomeStruct;
};
(the using declaration is just used to inherit all the constructors from Library::SomeStruct).
I think this is not possible without casting.
Basically there are two ways to do it:
1) Define p_ as void* and cast it in every function that uses it.
/* HEADER */
class Foo {
private:
void* p;
};
/* SOURCE */
#include <Library.h>
void Foo::AnyFunc()
{
Library::SomeStruct* pImpl = reinterpret_cast<Library::SomeStruct*>(p);
...
}
2) Create a "shadowing"-class of your class (in the .cpp-file) with all members cloned and p_ defined as Library::SomeStruct. Then cast the this-pointer to this shadowing class. This is of course a quite insecure and dirty hack which I don't recommend...
/* HEADER */
class Foo {
private:
void* p;
};
/* SOURCE */
#include <Library.h>
class FooImpl
{
public:
void AnyFunc() { p->DoSomething(); }
private:
Library::SomeStruct* p;
}
void Foo::AnyFunc()
{
FooImpl* pImpl = reinterpret_cast<FooImpl*>(this);
pImpl->AnyFunc();
}
This exploits memory structure and is therefore quite fragile (all members need to be in the same order and when you add or remove members, you need to update ShadowFoo, too). I mentioned this just for completeness.
3) This brings us to yet another, but more simple way: create the implementation in the source file and initialize it in the constructor with the void*-pointer:
/* HEADER */
class Foo {
private:
void* p;
};
/* SOURCE */
#include <Library.h>
class FooImpl
{
public:
FooImpl(void* pSomeStruct)
{
p = reinterpret_cast<Library::SomeStruct*>(pSomeStruct);
}
void AnyFunc() { p->DoSomething(); }
private:
Library::SomeStruct* p;
}
void Foo::AnyFunc()
{
FooImpl impl = FooImpl(p);
impl.AnyFunc();
}
I have a couple functions that I want to use in many different classes. I have a couple classes that are derived from one base class and so tried to make it so that the base class held the functions and then the child classes could just call them. This seemed to cause linking errors, and so following advice from this question (Advantages of classes with only static methods in C++) I decided to give namespaces a swing, but the only file that is included by every header/file is resource.h, and I don't want to put a namespace for my functions in there as it seems to specialised to mess with.
My question is, how do I make a class that only includes a namespace, or the functions I want to use, so that I can just include this class and use the functions as desired?
Thank you in advance for the help, the answers I've found on the internet only focus on one file, not multiple files like I'm hoping to address :)
You seem confused about how namespaces are used. Here are some things to keep in mind when working with namespaces:
You create a namespace using the syntax namespace identifier { /* stuff */ }. Everything between the { } will be in this namespace.
You cannot create a namespace inside a user-defined type or function.
A namespace is an open group construct. This means you can add more stuff into this namespace later on in some other piece of code.
Namespaces aren't declared unlike some of the other language constructs.
If you want certain classes and/or functions inside a namespace scope, enclose it with the namespace syntax in the header of where it's defined. Modules using those classes will see the namespace when the headers get #include'd.
For example, in your Entity.h you might do:
// Entity.h
#pragma once
namespace EntityModule{
class Entity
{
public:
Entity();
~Entity();
// more Entity stuff
};
struct EntityFactory
{
static Entity* Create(int entity_id);
};
}
inside your main.cpp you access it like this:
#include "Entity.h"
int main()
{
EntityModule::Entity *e = EntityModule::EntityFactory::Create(42);
}
If you also want Player to be inside this namespace then just surround that with namespace EntityModule too:
// Player.h
#pragma once
#include "Entity.h"
namespace EntityModule{
class Player : public Entity
{
// stuff stuff stuff
};
}
This works because of point #3 above.
If for some reason you feel you need to create a namespace inside a class, you can simulate this to an extent using nested classes:
class Entity
{
public:
struct InnerEntity
{
static void inner_stuff();
static int more_inner_stuff;
private:
InnerEntity();
InnerEntity(const InnerEntity &);
};
// stuff stuff stuff
};
Some important differences and caveats doing it this way though:
Everything is qualified with static to indicate there's no specific instance associated.
Can be passed as a template parameter.
Requires a ; at the end.
You can't create a convenient shorthand with abusing namespace Entity::InnerEntity;. But perhaps this is a good thing.
Unlike namespaces, class and struct are closed constructs. That means you cannot extend what members it contains once defined. Doing so will cause a multiple definition error.
You can put anything in a namespace, but you can't put namespaces inside things ( that's not a very formal way of saying it but I hope you get what I mean.
Valid
namespace foospace
{
class foo
{
public :
foo();
~foo();
void eatFoo();
};
}
Invalid
namespace foospace
{
class foo
{
public :
foo();
~foo();
namespace eatspace
{
void eatFoo();
}
};
}
I'm not 100% certain that the second example wouldn't compile, but regardless, you shouldn't do it.
Now, from your comments it sounds like you want something like this :
In the file Entity.h, your entity class definition :
namespace EntitySpace
{
class Entity
{
public :
Entity();
~Entity();
};
}
In the file Player.h
#include "Entity.h"
namespace EntitySpace
{
class Player : public Entity
{
public :
Player();
~Player();
};
}
In the file main.cpp
#include "Player.h"
int main()
{
EntitySpace::Player p1;
EntitySpace::Player p2;
}
So you call upon Player in the EntitySpace namespace. Hope this answers what you were asking.
I've got two classes, Entity and Level. Both need to access methods of one another. Therefore, using #include, the issue of circular dependencies arises. Therefore to avoid this, I attempted to forward declare Level in Entity.h:
class Level { };
However, as Entity needs access to methods in Level, it cannot access such methods, since it does not know they exist. Is there a way to resolve this without re-declaring the majority of Level in Entity?
A proper forward declaration is simply:
class Level;
Note the lack of curly braces. This tells the compiler that there's a class named Level, but nothing about the contents of it. You can then use pointers (Level *) and references (Level &) to this undefined class freely.
Note that you cannot directly instantiate Level since the compiler needs to know the class's size to create variables.
class Level;
class Entity
{
Level &level; // legal
Level level; // illegal
};
To be able to use Level in Entity's methods, you should ideally define Level's methods in a separate .cpp file and only declare them in the header. Separating declarations from definitions is a C++ best practice.
// entity.h
class Level;
class Entity
{
void changeLevel(Level &);
};
// entity.cpp
#include "level.h"
#include "entity.h"
void Entity::changeLevel(Level &level)
{
level.loadEntity(*this);
}
you two options:
use pointers in which case your forward declares should be ok.
inline the methods of one class, in which case if you include the .h file you can use the methods of the other.
Personally I would go down path number 1, it's cleaner and allows better access. I use a lot of shared_ptr so I do not have to worry about deletes...
Entity.h:
class Level;
class Entity {
private:
Level* m_pLevel;
public:
bool CheckLevel ();
bool WasItThere();
Level.h
class Entity;
class Level {
private:
Entity* m_pEntity;
public:
public bool CheckMyStuff();
public bool CheckItOut() { return m_pEntity->WasItThere();}
}
Entity.cpp
#include "Level.h"
bool Entity::CheckLevel () {
return true;
}
bool Entity::CheckLevel() {
return m_pLevel->CheckMyStuff();
}
bool Entity::WasItThere() {
return true;
}
Level.cpp
bool Level::CheckMyStuff() {
return true;
}
bool Level::CheckItOut() {
return m_pEntity->WasItThere();
}
I am trying to use the pimpl pattern and define the implementation class in an anonymous namespace. Is this possible in C++? My failed attempt is described below.
Is it possible to fix this without moving the implementation into a namespace with a name (or the global one)?
class MyCalculatorImplementation;
class MyCalculator
{
public:
MyCalculator();
int CalculateStuff(int);
private:
MyCalculatorImplementation* pimpl;
};
namespace // If i omit the namespace, everything is OK
{
class MyCalculatorImplementation
{
public:
int Calculate(int input)
{
// Insert some complicated calculation here
}
private:
int state[100];
};
}
// error C2872: 'MyCalculatorImplementation' : ambiguous symbol
MyCalculator::MyCalculator(): pimpl(new MyCalculatorImplementation)
{
}
int MyCalculator::CalculateStuff(int x)
{
return pimpl->Calculate(x);
}
No, the type must be at least declared before the pointer type can be used, and putting anonymous namespace in the header won't really work. But why would you want to do that, anyway? If you really really want to hide the implementation class, make it a private inner class, i.e.
// .hpp
struct Foo {
Foo();
// ...
private:
struct FooImpl;
boost::scoped_ptr<FooImpl> pimpl;
};
// .cpp
struct Foo::FooImpl {
FooImpl();
// ...
};
Foo::Foo() : pimpl(new FooImpl) { }
Yes. There is a work around for this. Declare the pointer in the header file as void*, then use a reinterpret cast inside your implementation file.
Note: Whether this is a desirable work-around is another question altogether. As is often said, I will leave that as an exercise for the reader.
See a sample implementation below:
class MyCalculator
{
public:
MyCalculator();
int CalculateStuff(int);
private:
void* pimpl;
};
namespace // If i omit the namespace, everything is OK
{
class MyCalculatorImplementation
{
public:
int Calculate(int input)
{
// Insert some complicated calculation here
}
private:
int state[100];
};
}
MyCalculator::MyCalculator(): pimpl(new MyCalculatorImplementation)
{
}
MyCalaculator::~MyCalaculator()
{
// don't forget to cast back for destruction!
delete reinterpret_cast<MyCalculatorImplementation*>(pimpl);
}
int MyCalculator::CalculateStuff(int x)
{
return reinterpret_cast<MyCalculatorImplementation*>(pimpl)->Calculate(x);
}
No, you can't do that. You have to forward-declare the Pimpl class:
class MyCalculatorImplementation;
and that declares the class. If you then put the definition into the unnamed namespace, you are creating another class (anonymous namespace)::MyCalculatorImplementation, which has nothing to do with ::MyCalculatorImplementation.
If this was any other namespace NS, you could amend the forward-declaration to include the namespace:
namespace NS {
class MyCalculatorImplementation;
}
but the unnamed namespace, being as magic as it is, will resolve to something else when that header is included into other translation units (you'd be declaring a new class whenever you include that header into another translation unit).
But use of the anonymous namespace is not needed here: the class declaration may be public, but the definition, being in the implementation file, is only visible to code in the implementation file.
If you actually want a forward declared class name in your header file and the implementation in an anonymous namespace in the module file, then make the declared class an interface:
// header
class MyCalculatorInterface;
class MyCalculator{
...
MyCalculatorInterface* pimpl;
};
//module
class MyCalculatorInterface{
public:
virtual int Calculate(int) = 0;
};
int MyCalculator::CalculateStuff(int x)
{
return pimpl->Calculate(x);
}
namespace {
class MyCalculatorImplementation: public MyCalculatorInterface {
...
};
}
// Only the ctor needs to know about MyCalculatorImplementation
// in order to make a new one.
MyCalculator::MyCalculator(): pimpl(new MyCalculatorImplementation)
{
}
markshiz and quamrana provided the inspiration for the solution below.
class Implementation, is intended to be declared in a global header file and serves as a void* for any pimpl application in your code base. It is not in an anonymous/unnamed namespace, but since it only has a destructor the namespace pollution remains acceptably limited.
class MyCalculatorImplementation derives from class Implementation. Because pimpl is declared as std::unique_ptr<Implementation> there is no need to mention MyCalculatorImplementation in any header file. So now MyCalculatorImplementation can be implemented in an anonymous/unnamed namespace.
The gain is that all member definitions in MyCalculatorImplementation are in the anonymous/unnamed namespace. The price you have to pay, is that you must convert Implementation to MyCalculatorImplementation. For that purpose a conversion function toImpl() is provided.
I was doubting whether to use a dynamic_cast or a static_cast for the conversion. I guess the dynamic_cast is the typical prescribed solution; but static_cast will work here as well and is possibly a little more performant.
#include <memory>
class Implementation
{
public:
virtual ~Implementation() = 0;
};
inline Implementation::~Implementation() = default;
class MyCalculator
{
public:
MyCalculator();
int CalculateStuff(int);
private:
std::unique_ptr<Implementation> pimpl;
};
namespace // Anonymous
{
class MyCalculatorImplementation
: public Implementation
{
public:
int Calculate(int input)
{
// Insert some complicated calculation here
}
private:
int state[100];
};
MyCalculatorImplementation& toImpl(Implementation& impl)
{
return dynamic_cast<MyCalculatorImplementation&>(impl);
}
}
// no error C2872 anymore
MyCalculator::MyCalculator() : pimpl(std::make_unique<MyCalculatorImplementation>() )
{
}
int MyCalculator::CalculateStuff(int x)
{
return toImpl(*pimpl).Calculate(x);
}