"Joseph Turian" <tu****@gmail.comwrote in message
news:11*********************@j44g2000cwa.googlegro ups.com
I am having difficulty defining a friend function because of a
#include cycle:
============ obj.H ================
#ifndef _obj_
#define _obj_
#include "cont.H"
class cont;
class obj {
friend void cont::foo(obj& o);
private:
void called_by_foo();
};
#endif
============ cont.H ================
#ifndef _cont_
#define _cont_
#include "obj.H"
#include <vector>
class cont {
public:
void foo(obj& o);
private:
std::vector<objv;
};
#endif
============ cont.C ================
#include"cont.H"
>gcc -o cont.o cont.C
In file included from cont.H:4,
from cont.C:1:
obj.H:9: error: member `void cont::foo(obj&)' declared as friend
before type `cont' defined
===============
How can I fix this such that cont can contain obj, but obj can have a
member function of cont as a friend function?
Thanks,
Joseph
If you wanted to also make a friend member declaration in cont, then you
would have a problem. However, since you only want to do it in obj, your
problem is probably soluble.
First note that you should NEVER use mutual inclusion because it it not
possible to achieve what you think you are achieving. When obj.h #includes
cont.h, that means you want cont.h read first. When cont.h #includes obj.h,
that means you want obj.h read first. Clearly, it is not possible for both
these things to be true; in any translation unit one file will be read first
and the other file will be read second. There is no way around that.
To make the member friend declaration, cont.h must be read first. Within
cont, you will need a forward declaration of obj.
By the way, you should not use leading underscores in your macro names lest
you hav a name clash with the implementation.
Your files should be:
///////////////////////////////////////////////////////////////////////
============ cont.H ================
#ifndef cont_
#define cont_
#include <vector>
class obj;
class cont {
public:
void foo(obj& o);
private:
std::vector<objv;
};
#endif
============ obj.H ================
#ifndef _obj_
#define _obj_
#include "cont.H"
class obj {
friend void cont::foo(obj& o);
private:
void called_by_foo();
};
#endif
============ cont.C ================
#include "obj.H"
/////////////////////////////////////////////////////////////////////////////////////
Not that the above scheme means that
std::vector<objv;
is being declared using an incomplete type. This is not guaranteed to
succeed, but does succeed on most implementations, including VC++ and
Comeau. If it doesn't succeed with your compiler, then you will need to
reverse the order of inclusion (read obj.h first and cont.h second) and make
the whole cont class a friend of obj, as per Victor's suggestion.
--
John Carson