-
March 5th, 2011, 10:34 AM
#1
[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?
-
March 5th, 2011, 11:14 AM
#2
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?
-
March 6th, 2011, 02:59 AM
#3
Re: how should I arrange classes in files?
Originally Posted by Feoggou
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.
-
March 7th, 2011, 10:40 AM
#4
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.
-
March 7th, 2011, 10:42 AM
#5
Re: how should I arrange classes in files?
Originally Posted by S_M_A
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.
-
March 7th, 2011, 12:20 PM
#6
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
{
};
}
-
March 7th, 2011, 01:14 PM
#7
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.
-
March 7th, 2011, 01:17 PM
#8
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!
-
March 7th, 2011, 01:42 PM
#9
Re: how should I arrange classes in files?
Originally Posted by Amleto
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.
-
March 7th, 2011, 01:44 PM
#10
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
-
March 7th, 2011, 01:51 PM
#11
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.
-
March 7th, 2011, 02:17 PM
#12
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.
-
March 7th, 2011, 02:32 PM
#13
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.
-
March 7th, 2011, 07:14 PM
#14
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;
};
}
-
March 8th, 2011, 05:07 AM
#15
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:
MainWnd.h includes:
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.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|