Thank you for your rapid reply, most helpful and ill follow that in the
future. I see your point about "namespace pollution", I just wanted to
make sure that explicitly defining things was indeed the way to go.
I was aware of the other things you have stated, the code that I posted
was uncompiled pseudo-code to illustrate my point. I guess I wrote it a
little too rapidly ;-).
Cheers,
Jon
Gavin Deane wrote:[color=blue]
> Jon Rea wrote:
>[color=green]
>>I am currently cleaning up an application which was origainlly hashed
>>together with speed of coding in mind and therefore contains quite a few
>>"hacky" shortcuts.
>>
>>As part of this "revamping" process I am introducing namespaces to
>>properly compartmentalise sections of the code into logical units. What
>>I am speciffically trying to get right is the dependency tree for header
>>files to reduce compile time and simplify the code structure.
>>
>>On this subject I have a few "best practise" questions:
>>
>>1) I realise that the whole point of a .h file is to keep the interface
>>separate from the implementation. What I would like to understand better
>>is exaclty what one should normally place in header files and if there
>>are exceptions.
>>
>>More specifically where should you place includes of system headers and
>>system namespaces? Should these normally go in the .h or the .cpp file?[/color]
>
>
> your header should include every other header it needs in order that it
> can be compiled on its own, and no more. In other words
>
> // header_test.cpp
> #include "my_header.h"
>
> This conceptual source file, which contains nothing but a single
> #include, should compile successfully for every one of your headers.
> Note that you can use forward declarations to reduce dependencies.
>
>[color=green]
>>Sometimes (i.e. when you are using templates) you need to put
>>implementation code in the header file. This implplementation is then
>>included in everything that references that header. If the file is used
>>lots, and/or many files cross-reference each other then the compilation
>>process is going to become slower and more complicated. Therefore header
>>files should reference each other as little as possible????[/color]
>
>
> Unless your compiler supports the export keyword, and you are happy to
> sacrifice portability to all compilers that don't, you are stuck with
> having template implementation code in the header.
>
>[color=green]
>>Are there any good internet articles on this subject (and on the other
>>things in this post)?
>>
>>2) What is best practise when classes are interdependent and in
>>different .h files? (Is adding 'class Class2;' the best way?):
>>
>>In class1.h:
>>----------------------
>>#include "class2.h"
>>
>>class Class2; // How does it work internally in the compiler? I read
>>somewhere that there is there any runtime penatly for this, but I cant
>>see why this would be so. Is there any penalty?
>>
>>class Class1
>>{
>> private:
>> Class2 m_C2;
>>};
>>----------------------
>>
>>In class2.h:
>>----------------------
>>#include "class1.h"
>>
>>class Class1;
>>
>>class Class2
>>{
>> private:
>> Class1 m_C2;
>>};
>>----------------------[/color]
>
>
> Did you try and compile this? A forward declaration is the way to fix
> this circular dependency problem. But you haven't gone far enough. Your
> Class1 contains a Class2 member, which contains a Class1 member, which
> contains a Class2 member, which contains .... and so on to infinity.
> See the FAQ
>
>
http://www.parashift.com/c++-faq-lit...html#faq-39.11
>
>[color=green]
>>3) Where should "using namespace" directievs go, in the .cpp file or in
>>the .h file?[/color]
>
>
> using directives and using declarations should not go in headers. They
> are convenience tools which are useful, however there is always a cost
> to using them. That cost is namespace pollution. To a certain extent
> using declarations and definitely using directives defeat the purpose
> of having namespaces in the first place. Within your own code you can
> always decide when you are prepared to accept that. If you put using
> declarations and directives in the header, everyone who includes that
> header, now and in the future, has that decision forced upon them
> whether they like it or not.
>
>[color=green]
>>Obviously compilation times are increased as interdependency inceases
>>between header files. Header files should be kept to a bare minimum in
>>what they include. Does adding a "using namsespace" to a header cause
>>extra compilation? or is its just effectively a set of default
>>namespaces in which to look for class names?[/color]
>
>
> It won't add to compilation. It just forces namespace pollution on
> every single user of the header, whether they like it or not.
>
>[color=green]
>>We have these classes:
>>
>>in file ClassNS1.h
>>----------------------
>>namespace NS1
>>{
>>class Class1
>>{
>>};
>>}
>>----------------------
>>
>>in file ClassNS2.h
>>----------------------
>>namespace NS2
>>{
>>class Class1
>>{
>>};
>>}
>>----------------------
>>
>>Is there any fundamental difference between these in terms of the
>>compilation process:
>>
>>in file invoke.h
>>----------------------
>>#include "ClassNS1.h"
>>using namespace NS1; // does this compile all of NS1 and include it
>>(i.e. big compile time penalty) ? or is this just a syntax shortcut
>>(i.e. no compile time penalty)?[/color]
>
>
> No compile time penalty. The using directive is not there to compile
> the code, purely to give the compiler more information about where to
> lookup names it encounters. But its use in a header is a bad idea as
> discussed above.
>
>[color=green]
>>class Invokation
>>{
>>public:
>>void Go();
>>private:
>>Class1 *m_Class1;
>>};
>>----------------------
>>in file invoke.cpp
>>#include "invoke.h"
>>void Invokation::Go()
>>{
>>m_Class1 = new Class1();
>>}
>>
>>in main.cpp
>>----------------------
>>void main()
>>{
>>Invokation *iv = new Invokation();
>>iv->Go();
>>}
>>----------------------[/color]
>
>
> Changing the subject for a moment, there are some style issues that you
> may be well aware of but i'll mention anyway.
>
> Go looks like it's doing work that should be in a constructor. Any
> reason it can't be done in a constructor?
> Any reason for creating iv dynamically?
> There is no delete to match the new.
> In standard C++ main returns int not void.
>
> As I say, these points don't have anything to do with your question.
> You may understand the issues perfectly well - this is example code
> after all. But they are also all relatively common errors from
> misunderstanding the language so I thought worth mentioning.
>
>[color=green]
>>OR THIS ??:
>>
>>in file invoke.h
>>----------------------
>>#include "ClassNS1.h"
>>class Invokation
>>{
>>public:
>>void Go();
>>private:
>>NS1::Class1 *m_Class1;[/color]
>
>
> That's the way to do it in a header.
>
>[color=green]
>>};
>>
>>in file invoke.cpp
>>#include "invoke.h"
>>void Invokation::Go()
>>{
>>m_Class1 = new Class1();[/color]
>
>
> Did you try and compile this? You've got rid of the using directive so
> the compiler will not look inside namespace NS1 for the name Class1.
> new NS1::Class1();
>
>[color=green]
>>}
>>----------------------
>>
>>in main.cpp
>>----------------------
>>void main()
>>{
>>Invokation *iv = new Invokation();
>>iv->Go();
>>}
>>----------------------[/color]
>
>
> Gavin Deane
>[/color]