#include cycles disallow 'friend' function?

Discussion in 'C++' started by Joseph Turian, Nov 21, 2006.

  1. 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<obj> v;
    };

    #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
     
    Joseph Turian, Nov 21, 2006
    #1
    1. Advertising

  2. Joseph Turian

    Guest

    Joseph Turian wrote:
    > 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<obj> v;
    > };
    >
    > #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


    I think you need the forward declaration of obj in cont.h
     
    , Nov 21, 2006
    #2
    1. Advertising

  3. Joseph Turian wrote:
    > I am having difficulty defining a friend function because of a
    > #include cycle:
    >
    > ============ obj.H ================
    > #ifndef _obj_
    > #define _obj_
    >
    > #include "cont.H"
    >
    > class cont;


    There is no sense forward-declaring a class if you include the
    file that contains its full definition. However, this does not
    seem to work for you. So, drop the inclusion altogether, then.

    >
    > class obj {
    > friend void cont::foo(obj& o);
    > private:
    > void called_by_foo();
    > };
    >
    > #endif
    > [..]
    > 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?


    You can't. Declare the entire class 'cont' a friend of 'obj'.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Nov 21, 2006
    #3
  4. wrote:
    > [..]
    > I think you need the forward declaration of obj in cont.h


    Which will do what, exactly?
     
    Victor Bazarov, Nov 21, 2006
    #4
  5. Joseph Turian

    Guest

    Victor Bazarov wrote:
    > wrote:
    > > [..]
    > > I think you need the forward declaration of obj in cont.h

    >
    > Which will do what, exactly?


    Unless there is another bug in VC++, but I did a quick addition of the
    forward declaration and that compiled.
    I think he had nested includes of header files which was causing one of
    the problems...
     
    , Nov 21, 2006
    #5
  6. Joseph Turian

    Pete Becker Guest

    Joseph Turian wrote:
    > I am having difficulty defining a friend function because of a #include
    > cycle:
    >


    Cyclic includes are never correct. Think it through: your source code
    pulls in cont.h. cont.h first defines the macro _cont_, then pulls in
    obj.h. obj.h first defines the macro _obj_, then pulls in cont.h. When
    compiling cont.h, the compiler sees that _cont_ is already defined, so
    it skips to the end of the ifndef block.

    The problem has nothing to do with friend functions. You're not getting
    the definition of cont at the point where you're using it in obj.h.

    --

    -- Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com)
    Author of "The Standard C++ Library Extensions: a Tutorial and
    Reference." (www.petebecker.com/tr1book)
     
    Pete Becker, Nov 21, 2006
    #6
  7. Joseph Turian

    John Carson Guest

    "Joseph Turian" <> wrote in message
    news:
    > 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<obj> v;
    > };
    >
    > #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<obj> v;
    };

    #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<obj> v;

    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
     
    John Carson, Nov 21, 2006
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Rich Wallace

    DataGrid - Disallow Postback?

    Rich Wallace, Jul 15, 2004, in forum: ASP .Net
    Replies:
    8
    Views:
    521
    Rich Wallace
    Jul 15, 2004
  2. Tim
    Replies:
    1
    Views:
    501
    Juha Laiho
    Feb 16, 2005
  3. =?ISO-8859-1?Q?Jan-Erik_=D6hman?=

    How to disallow empty string elements using XML Schema?

    =?ISO-8859-1?Q?Jan-Erik_=D6hman?=, Aug 28, 2003, in forum: XML
    Replies:
    0
    Views:
    537
    =?ISO-8859-1?Q?Jan-Erik_=D6hman?=
    Aug 28, 2003
  4. Andreas Bogenberger
    Replies:
    3
    Views:
    927
    Andreas Bogenberger
    Feb 22, 2008
  5. Peter
    Replies:
    2
    Views:
    276
    Öö Tiib
    Jun 6, 2013
Loading...

Share This Page