CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 22
  1. #1
    Join Date
    Aug 2006
    Location
    Timisoara, Romania
    Posts
    433

    [RESOLVED] how should I arrange classes in files?

    Do you know some "good practices"?

    I've came across certain situations where I had to add things to classes that required certain headers and the project could not have been compiled anymore because of things like: file1.h requires files2.h which requires file1.h.

    The last problem with things like this was this:
    File1.h contained the definition of Class1
    File2.h contained the definition of Class2
    File1.h declared Class2 as friend (which meant I had to #include File2.h in it)
    File2.h required data and data types from File1.h (which meant I had to #include File1.h in it)
    And it didn't compile.

    And I lose time trying to figure out how to make it work. Can anyone give some suggestions of "good practices" to avoid situations like this or to be able to solve them quicklier?

  2. #2
    Join Date
    Oct 2006
    Location
    Sweden
    Posts
    3,654

    Re: how should I arrange classes in files?

    You don't have to include any file for the friend declaration just use friend class XXX;

    When to classes share definitions like that why not have the shared stuff in a separate header?
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible, you are, by
    definition, not smart enough to debug it.
    - Brian W. Kernighan

    To enhance your chance's of getting an answer be sure to read
    http://www.codeguru.com/forum/announ...nouncementid=6
    and http://www.codeguru.com/forum/showthread.php?t=366302 before posting

    Refresh your memory on formatting tags here
    http://www.codeguru.com/forum/misc.php?do=bbcode

    Get your free MS compiler here
    https://visualstudio.microsoft.com/vs

  3. #3
    Join Date
    May 2009
    Posts
    2,413

    Re: how should I arrange classes in files?

    Quote Originally Posted by Feoggou View Post
    Can anyone give some suggestions of "good practices" to avoid situations like this or to be able to solve them quicklier?
    One way to avoid/break recursive dependencies is to follow these steps. The first step is to forward declare Class2 before the definition of Class1 in File1.h. This may require some fiddling but the goal is to reach a situation where File2.h doesn't need to be included in File1.h.

    Since this means File1.h cannot be use without File2.h also being included eventually, and since Class1 and Class2 are recursively dependent anyway, the second step is to introduce a new include file to reflect this, like,

    File3.h:
    #include "File1.h"
    #include "File2.h"

    Then File3.h is included whenever Class1 and/or Class2 are wanted.

    To reduce the number of include files I sometimes resort to skipping File1.h and File2.h altogether and put both class definitions on File3.h. (but the forward declaration is still needed)

    Still a much better way to resolve circular dependencies is by the way of design. The end result is that Class1 and Class2 aren't recursively dependent anymore and thus their include files won't conflict. So in fact a large number of conflicting include files may indicate a too tightly coupled design.
    Last edited by nuzzle; March 6th, 2011 at 03:42 AM.

  4. #4
    Join Date
    Aug 2006
    Location
    Timisoara, Romania
    Posts
    433

    Re: how should I arrange classes in files?

    ok, and if Class2 belongs to myNamespace, and thus, File2.h contains myNamespace which contains Class2, what is it best to do? Is there a way I can share a namespace without including the actual header file that contains it?

    for instance, a function member of a class requires a class defined in a namespace. Where should I declare the namespace?
    I have declared it in a header file, with:
    Code:
    class ClassX;
    class ClassY;
    but when I try to use ClassX, for instance, it tells me that the class has no constructor, though it has!
    Last edited by Feoggou; March 7th, 2011 at 12:27 PM.

  5. #5
    Join Date
    Aug 2006
    Location
    Timisoara, Romania
    Posts
    433

    Re: how should I arrange classes in files?

    Quote Originally Posted by S_M_A View Post
    When to classes share definitions like that why not have the shared stuff in a separate header?
    I don't understand what you mean. As far as I know, the definition of a class in c++ can belong in one header file only.

  6. #6
    Join Date
    Apr 2008
    Posts
    725

    Re: how should I arrange classes in files?

    a.h:
    Code:
    namespace a_
    {
    class a
    {
    };
    }
    b.h:
    Code:
    namespace a_
    {
      class a;
    }
    
    namespace b_
    {
      class b
      {
      };
    }

  7. #7
    Join Date
    Aug 2006
    Location
    Timisoara, Romania
    Posts
    433

    Re: how should I arrange classes in files?

    well, in my little bit complicated project, I use: I'll re-check and write:

    in general.h (general.h includes different header files):
    Code:
    namespace na
    {
          class ca;
    }
    bheader:
    Code:
    #include "general.h"
    
    class cb
    {
        void DoX()
        {
            na::ca obj(parameters);
         }
    };
    but I get the following errors:

    Code:
    error C2079: 'obj' uses undefined class 'na::ca'
    (a few of them)
    and then an intellisense error that says:
    Code:
    IntelliSense: no default constructor exists for class "na::ca"
    if I use this, instead, in bheader:
    Code:
    #include "general.h"//general.h does not contain namespace na anymore, here.
    
    namespace na
    {
          class ca;
    }
    
    class cb
    {
        void DoX()
        {
            na::ca obj(parameters);
         }
    };
    I get the following errors:
    Code:
    error C2757: 'na' :  a symbol with this name already exists and therefore this name cannot be used as a namespace name
    error C2027: use of undefined type 'na'
    error C2079: 'ca' uses undefined class 'na'
    error C2027: use of undefined type 'na'
    error C2146: syntax error : missing ';' before identifier 'obj'
    error C2065: 'obj' : undeclared identifier

    I don't understand what exactly the problem is.

    class ca is also declared in another header file - if I don't declare it there, the latter errors happen. If it is declared there, the foremost errors happen - in its namespace, na, and its contents is defined in a .cpp file.
    Last edited by Feoggou; March 7th, 2011 at 01:32 PM.

  8. #8
    Join Date
    Apr 2008
    Posts
    725

    Re: how should I arrange classes in files?

    you get the error because you only forward declared it. If you 'use' a type in a header, you MUST include it!

  9. #9
    Join Date
    Aug 2006
    Location
    Timisoara, Romania
    Posts
    433

    Re: how should I arrange classes in files?

    Quote Originally Posted by Amleto View Post
    you get the error because you only forward declared it. If you 'use' a type in a header, you MUST include it!
    if I do that I receive the following error:
    Code:
    error C2757: 'na' : a symbol with this name already exists and therefore this name cannot be used as a namespace name
    perhaps because that header file is included more than once.

  10. #10
    Join Date
    Apr 2008
    Posts
    725

    Re: how should I arrange classes in files?

    yes, you cannot include a header file more than once. are you using header gurads? It might be simplest to post all of your code in one post

  11. #11
    Join Date
    Aug 2006
    Location
    Timisoara, Romania
    Posts
    433

    Re: how should I arrange classes in files?

    header guards? you mean, as the Microsoft's #pragma once ? Then, yes. Otherwise, perhaps not.

    I don't know if I can post all my code in one post. Can I know the order in which files are included to draw on paper a scheme and see where the problem is and how to solve it? I know that the .cpp file the contains the main or WinMain function is the first one, but then there are the header fles it includes and the other .cpp files which I have no idea when they are included or if it should matter to me.

  12. #12
    Join Date
    Apr 2008
    Posts
    725

    Re: how should I arrange classes in files?

    just make sure that #pragma once is the first line in every header. The absolute first line.

    Not sure what the problem is:

    a.h
    Code:
    #pragma once
    
    namespace aa
    {
      class ClassA
      {
      };
    }
    b.h
    Code:
    #pragma once
    
    #include "a.h"
    
    namespace bb
    {
      class ClassB
      {
      public:
        void MakeA()
        {
          aa::ClassA objA;
        }
      };
    }
    main
    Code:
    #include "b.h"
    
    int main()
    {
      bb::ClassB aB;
      aB.MakeA();
    }

    if it gets more complicated, then remove the implementation of MakeA from the header and put it in a .cpp. then there is no need to include a.h in the b.h header!

    b.h
    Code:
    #pragma once
    
    //#include "a.h"
    
    namespace aa
    {
      class ClassA;
    }
    
    namespace bb
    {
      class ClassB
      {
      public:
        void MakeA();
      };
    }
    b.cpp
    Code:
    #include "b.h"
    
    #include "a.h"
    
    namespace bb
    {
      void ClassB::MakeA()
      {
        aa::ClassA a;
      }
    }
    Last edited by Amleto; March 7th, 2011 at 02:21 PM.

  13. #13
    Join Date
    Aug 2006
    Location
    Timisoara, Romania
    Posts
    433

    Re: how should I arrange classes in files?

    I do use #pragma once at the beginning of every header file.

    I've changed my code in a few places. Now I've gotten to a situation like this:

    file1.h:
    Code:
    namespace one
    {
    	class class1
    	{
    		int x;
    
    		friend class class2;
    	};
    }
    file2:
    Code:
    #include "file1.h"
    
    class class2
    {
    public:
    	int y;
    	class class2()
    	{
    		one::class1 obj;
    		obj.x = 3;
    	}
    };
    main.cpp:
    Code:
    #include "file2.h"
    ....
    //in the main function:
    class2 obj;
    And I get these errors in file2:
    Code:
    error C2248: 'one::class1::x' : cannot access private member declared in class 'one::class1'
    IntelliSense: member "one::class1::x" (declared at line 6 of "d:\my projects\testslearn\testslearn\file1.h") is inaccessible
    Why does the friendship not work? well... I assume it expects the class to belong in the same namespace. But, isn't there a way to do it without putting class2 in a namespace?

    it seems that friend class ::class2; does not work, even if class2 is global.
    It says:
    Code:
    error C2039: 'class2' : is not a member of '`global namespace''
    error C2248: 'one::class1::x' : cannot access private member declared in class 'one::class1'
    Last edited by Feoggou; March 7th, 2011 at 02:53 PM.

  14. #14
    Join Date
    Apr 2008
    Posts
    725

    Re: how should I arrange classes in files?

    I dont see that you have put pragma once anywhere. Anyway, this solves your problem:


    Code:
    #pragma once
    
    class class2;
    namespace one
    {
    	class class1
    	{
    		int x;
    
    		friend class2;
    	};
    }

  15. #15
    Join Date
    Aug 2006
    Location
    Timisoara, Romania
    Posts
    433

    Re: how should I arrange classes in files?

    thanks a lot.

    When I was writing friend class class2; I was thinking that it is the same as a class class2; + declare it as friend.

    As about the #pragma, I was in a hurry to put these sample code in a test project to test it, that's why I didn't included it then.

    It seems I've moved forward a bit... however, there is something left (due to a bit of modification to the code). Perhaps you can explain me why my class is not recognized:

    the files are like this:
    main.cpp contains WinMain, and includes:
    Code:
    #include "General.h"
    #include "Exceptions.h"
    General.h includes:
    Code:
    namespace App
    {
    	class MainWnd;
    	class VideoEngine;
    
    	extern MainWnd			mainWnd;
    	extern VideoEngine		m_Video;
    }
    
    #include "VideoEngine.h"
    #include "MainWnd.h"
    VideoEngine.h includes:
    Code:
    #include "General.h"
    #include "GameFont.h"
    //also, VideoEngine of App namespace is defined here (obviously)
    GameFont.h includes:
    Code:
    #include "General.h"
    #include "GraphicElement.h"
    #include "Exceptions.h"
    GraphicElement.h includes:
    Code:
    #include "General.h"
    //the error remains even if I #include "VideoEngine.h"
    //there is also a class GraphicElement which has an inline function:
    ID3D10Device* GetDevice() {return App::m_Video.m_pDevice;}
    but the problem is that I receive the error "error C2027: use of undefined type 'App::VideoEngine'"

    Exceptions.h includes:
    Code:
    #include General.h
    MainWnd.h includes:
    Code:
    #include General.h
    I supposes that VideoEngine.h should have already been included when it reached GraphicElement.h, but it doesn't work even if I #include "VideoEngine.h" specifically in it (as I've shown in comment above). Also, a class of the Exceptions.h file does not see the VideoEngine class, not even if I included specifically in Exceptions.h.

    Any suggestion why is not working? Please.
    Last edited by Feoggou; March 8th, 2011 at 06:47 AM.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured