Hi everyone,

I'm doing a little project after a long period of no c++, so please forgive me for any possible stupid mistakes.

Basically I have 2 cpp files, in first.cpp I define namespace 'myNS', and in second.cpp I define class 'myClass'. The problem is that I have a pointer of type myClass* in the namespace, and I need variables from the namespace in the myClass. So the 2 files look something like this:

//first.cpp
#ifndef FIRST_CPP
#define FIRST_CPP
#include "second.cpp"

namespace myNS
{
myClass* myClassPtr;
int justAnyNumber;
}
#endif

//second.cpp
#ifndef SECOND_CPP
#define SECOND_CPP
#include "first.cpp"

class myClass
{
public:
myClass()
{
myNS::justAnyNumber = 5; // Error here
}
}
#endif

When I compile this code I the error "myNS has not been declared". Now I understand that in this structure, the compiler/linker is trying to compile second.cpp before is reaches the definition of the namespace, but I'm still clueless on how to solve this issue.

Any ideas on how to solve this?

Recommended Answers

All 4 Replies

#include "first.cpp"

using namespace myNS;

Does that solve it?

No, it didn't work :S

I got "‘myNS’ is not a namespace-name", but thanks for the try anyway

OK, I have found a solution. It does not look so nice, but at least it works.

So here it goes:

//first.cpp
#ifndef FIRST_CPP
#define FIRST_CPP


namespace myNS
{
  int justAnyNumber;
}

#include "second.cpp"

{
  myClass* myClassPtr;
}
#endif

//second.cpp
#ifndef SECOND_CPP
#define SECOND_CPP
#include "first.cpp"

class myClass
{
  public:
    myClass()
    {
      myNS::justAnyNumber = 5; // Error here
    }
}
#endif

What I did is:
- Split the definition of the namespace into 2 parts, the first part which is needed by the class, and the second part which needs the class.
- Place the the first part in the beginning, then include the .cpp file of the class, then place the second part of the namespace definition.

Note: I would still like someone with more experience to have a look at this, as I don't particularly like having #include lines in the middle of the file.

What you have here is what is called "circular referencing" meaning that first.cpp needs what is in second.cpp to be defined and second.cpp needs what is in first.cpp to be defined (so what comes first, the egg or the chicken?).

Luckily, C++ has a mechanism built-in for that exact purpose, i.e. breaking circular referencing. This mechanism is called "forward-declarations". This is done by simply having an empty declaration of a class that is fully declared later but that can be used in the mean time to declare other stuff (only pointers and references to the forward-declared type).

In your case, the solution is very simple:

//first.cpp
#ifndef FIRST_CPP
#define FIRST_CPP

//forward-declaration of myClass.
class myClass;

namespace myNS
{
  myClass* myClassPtr; //now a pointer to myClass is legal even without including second.cpp, as long as it will eventually appear in the compilation unit.
  int justAnyNumber;
}
#endif

//NOTE HERE: first.cpp will not be compilable, but second.cpp will.

//second.cpp
#ifndef SECOND_CPP
#define SECOND_CPP
#include "first.cpp"

class myClass
{
  public:
    myClass()
    {
      myNS::justAnyNumber = 5;
    }
}
#endif

One remark: I think your usage of cpp files is a bit weird. The compiler will not complain, but any programmers looking at this will, because your are essentially using cpp files for what most programmers would put in header files (.h or .hpp). Since experienced programmers, as they look through source code, often open only header files to know what is in the code, they will be pissed off if they get confused about where types, classes and namespaces are defined and have to start looking through cpp files too. Better mostly split definitions, declarations and trivial functions in the headers, while only implementations in the cpp files (and, please, no #including of cpp files, unless it is for a good reason like template instantiation).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.