4

My initial suspicion was that there was a circular dependency in my code and went through Resolve header include circular dependencies. But this hasn't resolved my compilation errors. Here is the code with 3 classes - A, G & N.

//A.h

#ifndef A_H_
#define A_H_

class com::xxxx::test::G;

namespace com { namespace xxxx { namespace test {

class A {

public:
 A();
 ~A();
 void method1(void);

private:
 G* g;
};

} } }

#endif /* A_H_ */


//A.cpp

#include "A.h"
#include "G.h"

namespace com { namespace xxxx { namespace test {

A::A() {
 g = new com::xxxx::test::G();
}

A::~A() {
 delete g;
}

void A::method1() {
 g->method2(*this);
}

} } }


//G.h

#ifndef G_H_
#define G_H_

class com::xxxx::test::A;

namespace com { namespace xxxx { namespace test {

class G {
public:
 void method2(const A&);
};

} } }

#endif /* G_H_ */


//G.cpp

#include "N.h"

namespace com { namespace xxxx { namespace test {

void G::method2(const A& a) {
 N n(a, *this);
}

} } }


//N.h

#ifndef N_H_
#define N_H_

#include "A.h"
#include "G.h"

namespace com { namespace xxxx { namespace test {

class N {
public:
 N(const A& obj1, const G& obj2) : a(obj1), g(obj2) {}
 void method3(void);

private:
 A a;
 G g;
};

} } }

#endif /* N_H_ */

I am getting about 10 compilation errors in A.h and A.cpp I am listing the compilation errors below:

./src/A.h:11: error: 'com' has not been declared
../src/A.h:25: error: ISO C++ forbids declaration of 'G' with no type
../src/A.h:25: error: invalid use of '::'
../src/A.h:25: error: expected ';' before '*' token
../src/A.cpp: In constructor 'com::xxxx::test::A::A()':
../src/A.cpp:16: error: 'g' was not declared in this scope
../src/A.cpp: In destructor 'com::xxxx::test::A::~A()':
../src/A.cpp:20: error: 'g' was not declared in this scope
../src/A.cpp: In member function 'void com::xxxx::test::A::method1()':
../src/A.cpp:24: error: 'g' was not declared in this scope

What could be the mistake in the above code?

Thank you in advance,
Regards,
Raghava.

3
  • 6
    Please don't write Java in C++ :( Commented Aug 28, 2010 at 8:18
  • @KennyTM: What's java-like about this? The naming convention? Commented Aug 28, 2010 at 8:21
  • 1
    @KennyTM: I must admit that I come from Java and started working on this project recently. Please see my comment on Potatoswatter's post. Commented Aug 28, 2010 at 19:53

4 Answers 4

9

The forward declaration

 class com::xxxx::test::G;

is illegal. Members of a namespace must be declared within it.

namespace com { namespace xxxx { namespace test {
    class G;

Also, as Kenny says, namespaces aren't used like this in C++. Unless your project is distributed as a library or is of reasonably large size (dozens of files minimum), you probably don't need your own namespace.

Sign up to request clarification or add additional context in comments.

11 Comments

@Potatoswatter: What's that critique about namespaces about? I don't get it.
@sbi: it encourages you to just put using namespace everywhere, and then you end up with everything in the same namespace. A simple, flat structure (like the entire std lib being in namespace std) actually means that people will respect the namespace, rather than just try to get rid of it, like you do in .NET or Java where you have deep, verbose heirarchies.
@Raghava: Hierarchical namespaces are useful, and it's customary to hide implementation details in a nested namespace named detail. But namespaces don't serve a purpose besides preventing conflicts. Java, by contrast, has a kind of unified system for naming source trees and identifying software vendors in class names.
@Raghava: You cannot add anything to the Boost namespace. Any external library's namespace should be considered reserved. It's reasonable to have a top-level namespace for your organization, particularly if it distributes multiple proprietary libraries, like Adobe. (Edit: do they use nested spaces or just flat?) But code which is not a library should generally not be in a namespace. And what does the toplevel namespace com really achieve?
@Raghava: Um, Potatoswatter's last comment might have been misleading. You can add something to boost's namespace. Namespaces are open, and can be added to. However, that doesn't mean you should. The boost libraries are a set of very thoroughly peer-reviewed, to-class libraries. Anything being in namespace boost lives off that shine. If your code didn't undergo the strict review process, you shouldn't use their namespace.
|
5

When the compiler tries to compile a.cop, the first thing it encounters (included from a.h) is this:

class com::xxxx::test::G;

At this point there is nothing to tell the compiler what exactly com, xxxx and test are. Each of these can be either a namespace or a class. This also means that G is unclear, which leads to all other errors.

Comments

2

Is class com::xxxx::test::G; legal in C++ ? I would have written:

namespace com {
   namespace xxxx {
       namespace test {
          class G;
       }
   }
}

Comments

2

As others have pointed out, using class com::xxxx::test::G; is illegal.

The simpler conversion is (preserving inline-ness):

namespace com { namespace xxxx { namespace test { class G; } } }

I prefer this way of forward declaring because "grepping" does not show scope, whereas this syntax immediately lay it out for all to see.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.