By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,227 Members | 1,241 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,227 IT Pros & Developers. It's quick & easy.

Forward Referencing Question

P: n/a
Hi All,

I have this stange compiler error. I have a class B that includes
pointers to class A, therefore I have done forward referencing by doing
class A; at the start of the header file.

Ok well that works ok, but if I include the following

class B {

A* p1 ;
A* p2 ;

B(A* a1, A* a2) {p1 = a1 ; p2 = a2 ;}

bool operator==(const C2Clique& p) const { return
(a1->getId()==p.a1->getId ;)

}

Ok then I get an error messaging saying me that type A is undefined. I
have realised this is because I am using the ->getId() method of A in
the == in B.

So my question is that as A relies on B and vice versa how can I get
around this problem?

Adam
Jul 23 '05 #1
Share this Question
Share on Google+
14 Replies


P: n/a
Adam Hartshorne wrote:
Hi All,

I have this stange compiler error. I have a class B that includes
pointers to class A, therefore I have done forward referencing by doing
class A; at the start of the header file.

Ok well that works ok, but if I include the following

class B {

A* p1 ;
A* p2 ;

B(A* a1, A* a2) {p1 = a1 ; p2 = a2 ;}

bool operator==(const C2Clique& p) const { return
(a1->getId()==p.a1->getId ;)

}

Ok then I get an error messaging saying me that type A is undefined. I
have realised this is because I am using the ->getId() method of A in
the == in B.

So my question is that as A relies on B and vice versa how can I get
around this problem?


Put the implementation of the operator== into the .cpp file.

Jul 23 '05 #2

P: n/a
Adam Hartshorne wrote:

So my question is that as A relies on B and vice versa how can I get
around this problem?

Don't inline the method body.

eg. change

class A {
....
void f() { ... }
....
};
class B { ... };

into:

class A {
....
void f();
....
};
class B { ... };

void A::f() { ... }

Of course, what you really want to do (what I would do anyway) is define
the class in a .h include file for each class (eg. A.h and B.h) and
create an implementation for each class (eg. A.cpp and B.cpp). Then in
your B.h just include A.h before the class.
Adam

--
Peter MacMillan
e-mail/msn: pe***@writeopen.com
icq: 1-874-927

GCS/IT/L d-(-)>-pu s():(-) a- C+++(++++)>$ UL>$ P++ L+ E-(-) W++(+++)>$
N o w++>$ O !M- V PS PE Y+ t++ 5 X R* tv- b++(+) DI D+(++)>$ G e++ h r--
y(--)
Jul 23 '05 #3

P: n/a
Peter MacMillan wrote:
Adam Hartshorne wrote:

So my question is that as A relies on B and vice versa how can I get
around this problem?


Don't inline the method body.

eg. change

class A {
...
void f() { ... }
...
};
class B { ... };

into:

class A {
...
void f();
...
};
class B { ... };

void A::f() { ... }

Of course, what you really want to do (what I would do anyway) is define
the class in a .h include file for each class (eg. A.h and B.h) and
create an implementation for each class (eg. A.cpp and B.cpp). Then in
your B.h just include A.h before the class.
Adam


I have done the following and stilll receive error messages

in .h file

#ifndef __RMFSITE_H_INCLUDED__
#define __RMFSITE_H_INCLUDED__

class RmfSite;

class C2Clique {

RmfSite* s1 ;
RmfSite* s2 ;

C2Clique(RmfSite* site1, RmfSite* site2) ;
bool C2Clique::operator==(const C2Clique& p) const ;

} ;

#endif

and in .cpp

#include "cliques.h"
#include "rmfSite.h"

C2Clique::C2Clique(RmfSite* site1, RmfSite* site2) {s1 = site1 ; s2 =
site2 ;}

bool C2Clique::operator==(const C2Clique& p) const { return
(s1->getId()==p.s1->getId() && s2->getId()==p.s2->getId()) ||
(s1->getId()==p.s2->getId() && s2->getId()==p.s1->getId()); }
Jul 23 '05 #4

P: n/a
Peter MacMillan wrote:
Adam Hartshorne wrote:

So my question is that as A relies on B and vice versa how can I get
around this problem?


Don't inline the method body.

eg. change

class A {
...
void f() { ... }
...
};
class B { ... };

into:

class A {
...
void f();
...
};
class B { ... };

void A::f() { ... }

Of course, what you really want to do (what I would do anyway) is define
the class in a .h include file for each class (eg. A.h and B.h) and
create an implementation for each class (eg. A.cpp and B.cpp). Then in
your B.h just include A.h before the class.
Adam


I should have said that I still get an RmfSite undefined error, and if I
try to move things around so that the #include in rmfSite.h is the first
called include I get an undefined in the .h file of the RmfSite Class.

Does this mean I have to put all the method in the .cpp for the RmfSite?

Adam
Jul 23 '05 #5

P: n/a
Adam Hartshorne wrote:
Peter MacMillan wrote:
Adam Hartshorne wrote:

So my question is that as A relies on B and vice versa how can I get
around this problem?


Don't inline the method body.

eg. change

class A {
...
void f() { ... }
...
};
class B { ... };

into:

class A {
...
void f();
...
};
class B { ... };

void A::f() { ... }

Of course, what you really want to do (what I would do anyway) is
define the class in a .h include file for each class (eg. A.h and B.h)
and create an implementation for each class (eg. A.cpp and B.cpp).
Then in your B.h just include A.h before the class.
Adam


I have done the following and stilll receive error messages

in .h file

#ifndef __RMFSITE_H_INCLUDED__
#define __RMFSITE_H_INCLUDED__

class RmfSite;

class C2Clique {

RmfSite* s1 ;
RmfSite* s2 ;

C2Clique(RmfSite* site1, RmfSite* site2) ;
bool C2Clique::operator==(const C2Clique& p) const ;

} ;

#endif

and in .cpp

#include "cliques.h"
#include "rmfSite.h"

C2Clique::C2Clique(RmfSite* site1, RmfSite* site2) {s1 = site1 ; s2 =
site2 ;}

bool C2Clique::operator==(const C2Clique& p) const { return
(s1->getId()==p.s1->getId() && s2->getId()==p.s2->getId()) ||
(s1->getId()==p.s2->getId() && s2->getId()==p.s1->getId()); }


Oh further information, I set a global std::list<C2Clique*> in the .h
file of the RmfSite class. What can I do now?? I can't put that in the
..cpp file of the RmfSite!

Adam
Jul 23 '05 #6

P: n/a
Adam Hartshorne schrieb:
Peter MacMillan wrote:
Adam Hartshorne wrote:

So my question is that as A relies on B and vice versa how can I get
around this problem?

Don't inline the method body.

eg. change

class A {
...
void f() { ... }
...
};
class B { ... };

into:

class A {
...
void f();
...
};
class B { ... };

void A::f() { ... }

Of course, what you really want to do (what I would do anyway) is
define the class in a .h include file for each class (eg. A.h and B.h)
and create an implementation for each class (eg. A.cpp and B.cpp).
Then in your B.h just include A.h before the class.
Adam


I have done the following and stilll receive error messages

in .h file

#ifndef __RMFSITE_H_INCLUDED__
#define __RMFSITE_H_INCLUDED__


Is this rmfSite.h or cliques.h? In the latter case, the above include
guard is wrong ;-) besides, names containing two consecutive underscores
are reserved for the implementation.
class RmfSite;

class C2Clique {

RmfSite* s1 ;
RmfSite* s2 ;

C2Clique(RmfSite* site1, RmfSite* site2) ;
bool C2Clique::operator==(const C2Clique& p) const ;

} ;

#endif

and in .cpp

#include "cliques.h"
#include "rmfSite.h"

C2Clique::C2Clique(RmfSite* site1, RmfSite* site2) {s1 = site1 ; s2 =
site2 ;}
Use of initialisation lists is preferred:
C2Clique::C2Clique(RmfSite* site1, RmfSite* site2) : s1(site1), s2(site2) {}

This one could still be defined inline, as it only assigns pointers
bool C2Clique::operator==(const C2Clique& p) const { return
(s1->getId()==p.s1->getId() && s2->getId()==p.s2->getId()) ||
(s1->getId()==p.s2->getId() && s2->getId()==p.s1->getId()); }


HTH,
Malte
Jul 23 '05 #7

P: n/a
Adam Hartshorne wrote:
I have done the following and stilll receive error messages

in .h file

#ifndef __RMFSITE_H_INCLUDED__
#define __RMFSITE_H_INCLUDED__

class RmfSite;

class C2Clique {

RmfSite* s1 ;
RmfSite* s2 ;

C2Clique(RmfSite* site1, RmfSite* site2) ;
bool C2Clique::operator==(const C2Clique& p) const ;

} ;
why are you defining C2Clique in a file called RmfSite.h? This isn't
what I meant (read on...)

#endif

and in .cpp

#include "cliques.h"
#include "rmfSite.h"

C2Clique::C2Clique(RmfSite* site1, RmfSite* site2) {s1 = site1 ; s2 =
site2 ;}

bool C2Clique::operator==(const C2Clique& p) const { return
(s1->getId()==p.s1->getId() && s2->getId()==p.s2->getId()) ||
(s1->getId()==p.s2->getId() && s2->getId()==p.s1->getId()); }


You still havent declared rmfSite. rmfSite.h should have a decleration
of the rmfSite class but you have it above with a decleration of the
C2Clique file... or I'm missing somthing here.

observe:

//
// A.h
//
#ifndef __A_H__
#define __A_H__

class A {
//...
public:
void f();
//...
};

#endif

//
// A.cpp
//
void A::f() { /* ... */ }
//
// B.h
//
#ifndef __B_H__
#define __B_H__

#include "A.h"

class B {
A* m_a;

public:
B(A* a) { m_a = a; }
void callA();
};

#endif

//
// B.cpp
//
#include "B.h"

void B::callA() {
m_a->f();
}
--
Peter MacMillan
e-mail/msn: pe***@writeopen.com
icq: 1-874-927

GCS/IT/L d-(-)>-pu s():(-) a- C+++(++++)>$ UL>$ P++ L+ E-(-) W++(+++)>$
N o w++>$ O !M- V PS PE Y+ t++ 5 X R* tv- b++(+) DI D+(++)>$ G e++ h r--
y(--)
Jul 23 '05 #8

P: n/a
Malte Starostik wrote:
Adam Hartshorne schrieb:
Peter MacMillan wrote:

Adam Hartshorne wrote:
So my question is that as A relies on B and vice versa how can I get
around this problem?
Don't inline the method body.

eg. change

class A {
...
void f() { ... }
...
};
class B { ... };

into:

class A {
...
void f();
...
};
class B { ... };

void A::f() { ... }

Of course, what you really want to do (what I would do anyway) is
define the class in a .h include file for each class (eg. A.h and B.h)
and create an implementation for each class (eg. A.cpp and B.cpp).
Then in your B.h just include A.h before the class.
Adam

I have done the following and stilll receive error messages

in .h file

#ifndef __RMFSITE_H_INCLUDED__
#define __RMFSITE_H_INCLUDED__

Is this rmfSite.h or cliques.h? In the latter case, the above include
guard is wrong ;-) besides, names containing two consecutive underscores
are reserved for the implementation.

class RmfSite;

class C2Clique {

RmfSite* s1 ;
RmfSite* s2 ;

C2Clique(RmfSite* site1, RmfSite* site2) ;
bool C2Clique::operator==(const C2Clique& p) const ;

} ;

#endif

and in .cpp

#include "cliques.h"
#include "rmfSite.h"

C2Clique::C2Clique(RmfSite* site1, RmfSite* site2) {s1 = site1 ; s2 =
site2 ;}

Use of initialisation lists is preferred:
C2Clique::C2Clique(RmfSite* site1, RmfSite* site2) : s1(site1), s2(site2) {}

This one could still be defined inline, as it only assigns pointers

bool C2Clique::operator==(const C2Clique& p) const { return
(s1->getId()==p.s1->getId() && s2->getId()==p.s2->getId()) ||
(s1->getId()==p.s2->getId() && s2->getId()==p.s1->getId()); }

HTH,
Malte


I still receive my undefined RmfSite error if

#include "cliques.h"
#include "rmfSite.h"

and a C2Clique is not a class or namespace name error if

#include "rmfSite.h"
#include "cliques.h"
Jul 23 '05 #9

P: n/a
Peter MacMillan wrote:
Adam Hartshorne wrote:
I have done the following and stilll receive error messages

in .h file

#ifndef __RMFSITE_H_INCLUDED__
#define __RMFSITE_H_INCLUDED__

class RmfSite;

class C2Clique {

RmfSite* s1 ;
RmfSite* s2 ;

C2Clique(RmfSite* site1, RmfSite* site2) ;
bool C2Clique::operator==(const C2Clique& p) const ;

} ;

why are you defining C2Clique in a file called RmfSite.h? This isn't
what I meant (read on...)

#endif

and in .cpp

#include "cliques.h"
#include "rmfSite.h"

C2Clique::C2Clique(RmfSite* site1, RmfSite* site2) {s1 = site1 ; s2 =
site2 ;}

bool C2Clique::operator==(const C2Clique& p) const { return
(s1->getId()==p.s1->getId() && s2->getId()==p.s2->getId()) ||
(s1->getId()==p.s2->getId() && s2->getId()==p.s1->getId()); }

You still havent declared rmfSite. rmfSite.h should have a decleration
of the rmfSite class but you have it above with a decleration of the
C2Clique file... or I'm missing somthing here.

observe:

//
// A.h
//
#ifndef __A_H__
#define __A_H__

class A {
//...
public:
void f();
//...
};

#endif

//
// A.cpp
//
void A::f() { /* ... */ }
//
// B.h
//
#ifndef __B_H__
#define __B_H__

#include "A.h"

class B {
A* m_a;

public:
B(A* a) { m_a = a; }
void callA();
};

#endif

//
// B.cpp
//
#include "B.h"

void B::callA() {
m_a->f();
}

No i have declared C2Clique in cliques.h and cliques.cpp and RmfSite in
rmfsite.h and rmfSite.cpp

Adam
Jul 23 '05 #10

P: n/a
Adam Hartshorne wrote:
I should have said that I still get an RmfSite undefined error, and if I
try to move things around so that the #include in rmfSite.h is the first
called include I get an undefined in the .h file of the RmfSite Class.

Does this mean I have to put all the method in the .cpp for the RmfSite?

Adam


A less code answer (I like using code examples) is that you have to
actually declare the bits of A before you start calling them. The point
of a header file (or a point, that is) is to declare the class. All
you've posted so far is a forward decleration. This is good enough for
resolving pointers and the like, but it's not enough for code (and
especially dereferencing those pointers). With only a forward
decleration available, the code only knows of the type - not the
contents of that type. So x->a() is invalid if all you've got so far is
class X (where x is presumeably an instance of X).

See the example in my other post about what goes where. hmm...
--
Peter MacMillan
e-mail/msn: pe***@writeopen.com
icq: 1-874-927

GCS/IT/L d-(-)>-pu s():(-) a- C+++(++++)>$ UL>$ P++ L+ E-(-) W++(+++)>$
N o w++>$ O !M- V PS PE Y+ t++ 5 X R* tv- b++(+) DI D+(++)>$ G e++ h r--
y(--)
Jul 23 '05 #11

P: n/a
Peter MacMillan wrote:
Adam Hartshorne wrote:
I should have said that I still get an RmfSite undefined error, and if
I try to move things around so that the #include in rmfSite.h is the
first called include I get an undefined in the .h file of the RmfSite
Class.

Does this mean I have to put all the method in the .cpp for the RmfSite?

Adam

A less code answer (I like using code examples) is that you have to
actually declare the bits of A before you start calling them. The point
of a header file (or a point, that is) is to declare the class. All
you've posted so far is a forward decleration. This is good enough for
resolving pointers and the like, but it's not enough for code (and
especially dereferencing those pointers). With only a forward
decleration available, the code only knows of the type - not the
contents of that type. So x->a() is invalid if all you've got so far is
class X (where x is presumeably an instance of X).

See the example in my other post about what goes where. hmm...

As far as I can see this exactly what I have,
c2clique.h

#ifndef __RMFSITE_H_INCLUDED__
#define __RMFSITE_H_INCLUDED__

class C2Clique {

RmfSite* s1 ;
RmfSite* s2 ;

C2Clique(RmfSite* site1, RmfSite* site2) {s1 = site1 ; s2 = site2 ;}
~C2Clique() {}
bool C2Clique::operator==(const C2Clique& p) const ;

} ;

#endif
c2clique.cpp

#include "rmfSite.h"

bool C2Clique::operator==(const C2Clique& p) const { return
(s1->getId()==p.s1->getId() && s2->getId()==p.s2->getId()) ||
(s1->getId()==p.s2->getId() && s2->getId()==p.s1->getId()); }
and in RmfSite.h I have to have a std::list<C2Cliques*>. But my error is
coming from the c2clique.cpp file with the error message

C2Clique is not a class or namespace name
Adam

Jul 23 '05 #12

P: n/a
Adam Hartshorne schrieb:
Peter MacMillan wrote:
Adam Hartshorne wrote:
I have done the following and stilll receive error messages

in .h file

#ifndef __RMFSITE_H_INCLUDED__
#define __RMFSITE_H_INCLUDED__ ^^^^^^^^^^^^^^^^^^^^^^
class RmfSite;

class C2Clique {

RmfSite* s1 ;
RmfSite* s2 ;

C2Clique(RmfSite* site1, RmfSite* site2) ;
bool C2Clique::operator==(const C2Clique& p) const ;

} ;

No i have declared C2Clique in cliques.h and cliques.cpp and RmfSite in
rmfsite.h and rmfSite.cpp


Yes, but it seems you copied the include guard from RmfSite.h to
cliques.h without chaning it accordingly (see above and my other post),
so if you #include both in the same translation unit, only the first one
will make it to the compiler after preprocessing.

Cheers,
Malte
Jul 23 '05 #13

P: n/a
Adam Hartshorne wrote:
Peter MacMillan wrote:
Adam Hartshorne wrote:
I should have said that I still get an RmfSite undefined error, and
if I try to move things around so that the #include in rmfSite.h is
the first called include I get an undefined in the .h file of the
RmfSite Class.

Does this mean I have to put all the method in the .cpp for the RmfSite?

Adam


A less code answer (I like using code examples) is that you have to
actually declare the bits of A before you start calling them. The
point of a header file (or a point, that is) is to declare the class.
All you've posted so far is a forward decleration. This is good enough
for resolving pointers and the like, but it's not enough for code (and
especially dereferencing those pointers). With only a forward
decleration available, the code only knows of the type - not the
contents of that type. So x->a() is invalid if all you've got so far
is class X (where x is presumeably an instance of X).

See the example in my other post about what goes where. hmm...

As far as I can see this exactly what I have,
c2clique.h

#ifndef __RMFSITE_H_INCLUDED__
#define __RMFSITE_H_INCLUDED__

class C2Clique {

RmfSite* s1 ;
RmfSite* s2 ;

C2Clique(RmfSite* site1, RmfSite* site2) {s1 = site1 ; s2 =
site2 ;}
~C2Clique() {}
bool C2Clique::operator==(const C2Clique& p) const ;

} ;

#endif
c2clique.cpp

#include "rmfSite.h"

bool C2Clique::operator==(const C2Clique& p) const { return
(s1->getId()==p.s1->getId() && s2->getId()==p.s2->getId()) ||
(s1->getId()==p.s2->getId() && s2->getId()==p.s1->getId()); }
and in RmfSite.h I have to have a std::list<C2Cliques*>. But my error is
coming from the c2clique.cpp file with the error message

C2Clique is not a class or namespace name
Adam

Also if I add into c2clique.cpp

#include "c2clique.h" before the include of the rmfSite I get the
following message

syntax error : missing ';' before '*'

Adam
Jul 23 '05 #14

P: n/a
Malte Starostik wrote:
Adam Hartshorne schrieb:
Peter MacMillan wrote:

Adam Hartshorne wrote:
I have done the following and stilll receive error messages

in .h file

#ifndef __RMFSITE_H_INCLUDED__
#define __RMFSITE_H_INCLUDED__
^^^^^^^^^^^^^^^^^^^^^^
class RmfSite;

class C2Clique {

RmfSite* s1 ;
RmfSite* s2 ;

C2Clique(RmfSite* site1, RmfSite* site2) ;
bool C2Clique::operator==(const C2Clique& p) const ;

} ;


No i have declared C2Clique in cliques.h and cliques.cpp and RmfSite in
rmfsite.h and rmfSite.cpp

Yes, but it seems you copied the include guard from RmfSite.h to
cliques.h without chaning it accordingly (see above and my other post),
so if you #include both in the same translation unit, only the first one
will make it to the compiler after preprocessing.

Cheers,
Malte

Thank you guys for all the help. I have Spotted the include guard
problem. I bet you can't guess who is working at 3.30am :-) and making
trivial mistakes

Adam
Jul 23 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.