Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. About friend classes
QtWS25 Last Chance

About friend classes

Scheduled Pinned Locked Moved Unsolved C++ Gurus
5 Posts 4 Posters 5.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    mulfycrowh
    wrote on 3 Aug 2016, 17:33 last edited by
    #1

    Hi,

    I have two classes A, B.
    B is a friend of class A.
    I use VS2015.

    So I wrote the following headers and cpp:

    A.h

    #ifndef A_H
    #define A_H
    
    class B;
    
    class A
    {
    private:
    ...
    
    public:
    ...
    friend class B;
    }
    
    #endif
    

    B.h

    #ifndef B_H
    #define B_H
    
    class A;
    
    class B
    {
    private:
    A* a;
    
    public:
    void B::writeHeader();
    ...
    }
    #endif
    

    B.cpp

    void B::writeHeader()
    {
    	a->... = ...
    }
    

    The issue is in function writeHeader().
    As I start to type a->, VS 2015 doesn't display the list of private mebers of the class A. I does when I replace class A; with #include "A;h".
    Could you explain please ?
    Thanks

    1 Reply Last reply
    0
    • J Offline
      J Offline
      jeremy_k
      wrote on 3 Aug 2016, 22:10 last edited by
      #2

      Include A.h in B.cpp. Otherwise, the IDE doesn't know what A is.

      Asking a question about code? http://eel.is/iso-c++/testcase/

      1 Reply Last reply
      0
      • P Offline
        P Offline
        Paul Colby
        wrote on 3 Aug 2016, 22:22 last edited by
        #3

        @mulfycrowh said:

        As I start to type a->, VS 2015 doesn't display the list of private mebers of the class A. I does when I replace class A; with #include "A;h".
        Could you explain please ?

        That's pretty normal. Basically, the class A; is forward declaration that the tells the compiler (and VS) that some class "A" exists somewhere, but doesn't tell it anything about what A actually is.

        Used in this way, there's very little the compiler can do with A, because it doesn't know what it is. The one real exception being, that you can declare a pointer to A as part of B (member variables, etc).

        To actually use A in any other way (including dereferencing pointers to A), requires a the compiler (and VS) to know what A actually is, and usual (including your case), that means including A.h.

        For example:

        // B.h
        class A;
        
        class B {
            ....
            A *a;
        }
        
        // B.cpp
        #include "A.h"
        
        B::B() {
            a->... // Okay, since we've included "A.h"
        }
        

        So then, if A.h is available, why not simply include it in B.h and not bother with the class A; forward declaration? The answer is mostly (IMO) compile-time performance. If, for example, we had some class C that used B, but not A, then as shown above, C.h can include B.h without the compiler having to parse (unnecessarily) all of A.h too. In this super-simple example, the difference in negligible, but for large scale projects / libraries such as Qt, the difference can be massive (both in time and memory usages during compilation).

        Some optional further reading:

        • http://stackoverflow.com/questions/9906402/should-one-use-forward-declarations-instead-of-includes-wherever-possible (they say "yes")
        • https://google.github.io/styleguide/cppguide.html#Forward_Declarations (they say "no")

        Cheers.

        K 1 Reply Last reply 3 Aug 2016, 22:27
        1
        • P Paul Colby
          3 Aug 2016, 22:22

          @mulfycrowh said:

          As I start to type a->, VS 2015 doesn't display the list of private mebers of the class A. I does when I replace class A; with #include "A;h".
          Could you explain please ?

          That's pretty normal. Basically, the class A; is forward declaration that the tells the compiler (and VS) that some class "A" exists somewhere, but doesn't tell it anything about what A actually is.

          Used in this way, there's very little the compiler can do with A, because it doesn't know what it is. The one real exception being, that you can declare a pointer to A as part of B (member variables, etc).

          To actually use A in any other way (including dereferencing pointers to A), requires a the compiler (and VS) to know what A actually is, and usual (including your case), that means including A.h.

          For example:

          // B.h
          class A;
          
          class B {
              ....
              A *a;
          }
          
          // B.cpp
          #include "A.h"
          
          B::B() {
              a->... // Okay, since we've included "A.h"
          }
          

          So then, if A.h is available, why not simply include it in B.h and not bother with the class A; forward declaration? The answer is mostly (IMO) compile-time performance. If, for example, we had some class C that used B, but not A, then as shown above, C.h can include B.h without the compiler having to parse (unnecessarily) all of A.h too. In this super-simple example, the difference in negligible, but for large scale projects / libraries such as Qt, the difference can be massive (both in time and memory usages during compilation).

          Some optional further reading:

          • http://stackoverflow.com/questions/9906402/should-one-use-forward-declarations-instead-of-includes-wherever-possible (they say "yes")
          • https://google.github.io/styleguide/cppguide.html#Forward_Declarations (they say "no")

          Cheers.

          K Offline
          K Offline
          kshegunov
          Moderators
          wrote on 3 Aug 2016, 22:27 last edited by
          #4

          @Paul-Colby said:

          So then, if A.h is available, why not simply include it in B.h and not bother with the class A; forward declaration? The answer is mostly (IMO) compile-time performance.

          There are two better reasons to do it, beside the compile time performance.

          1. Breaking cyclic dependency (A uses B, and B uses A)
          2. Hiding private/implementation information.

          Read and abide by the Qt Code of Conduct

          1 Reply Last reply
          2
          • M Offline
            M Offline
            mulfycrowh
            wrote on 4 Aug 2016, 09:52 last edited by
            #5

            Many thanks to everybody for These explanations !

            1 Reply Last reply
            0

            3/5

            3 Aug 2016, 22:22

            • Login

            • Login or register to search.
            3 out of 5
            • First post
              3/5
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved