Define C++ class in Java way - c++

This maybe not a real question, please close this if it's not appropriate.
In C++, you can't mix the header and implementation in a single source file, for example, the class will be defined twice if it's included by a.cc and b.cc:
// foo.h
#pragma once
class Foo {
void bar() { ... }
};
// a.cc
#include "foo.h"
class A {};
// b.cc
#include "foo.h"
class B {};
// Link all
$ gcc -c -o a.o a.cc
$ gcc -c -o b.o b.cc
$ gcc -o main main.cc foo.o a.o b.o
Then, it's ambiguous Foo::bar() in three object files!
Instead, we must separate the implementation into another file:
// foo.h
#pragma once
class Foo {
void bar();
};
// foo.cc
# include "foo.h"
void Foo::bar() { ... }
Though maybe not a big problem, because usually the binary for foo::bar() in a.o and b.o are the same. But at least there's some redundant declarations, isn't it? And some more confusions caused by this redundant:
Where to give the default values for the optional parameters?
class Foo {
void bar(int x = 100);
};
or,
void Foo::bar(int x = 100) { ... }
or, both?
Move between inline & not inline...?
If you want to switch a non-inlined function to an inlined one, you should move the code from foo.cc to foo.h, and add the inline keyword prefix. And maybe two seconds later, you are regreted what you've done, then, you move out the inlined one in foo.h back to the foo.cc and remove the inline keyword again.
But you won't need to do so if the declaration and definition are sit together.
And there are more of this kind of minor headaches.
The idea is, if you write the definition of a function just along with the declaration, along, there is no way a compiler couldn't infer the prototype of a function.
For example, by using a single source.cc, and import the type information only, for example,
#include_typedef "source.cc"
Things will be simpler. It's easy for a compiler to ignore variable allocation and function definitions by just filter at parser time even before constructing the AST, isn't it?
I'm used to programming in separate source/header files, I'm certainly capable of doing the separation. You can argue on the programming style, but, that will degrade the question what's the correct way to represent logics to what's the better programming style. I don't think Java is a better programming style, in the source/header separation context. but Java gives the correct way.
Do you mind to separate the headers from the classes?
If possible, how will you mix them into one?
Is there any C++ front-end which can separate the declaration and definition into separate files from mixed sources? Or how can I write such one? (I mean to the GCC.)
EDIT
I'm not bashing C++ anyway, I'm sorry if you get wrong information from this question.
As C++ is a multi paradigm language, you can see how MFC setup message bindings by using magic macros, and how boost library implements everything using templates. When the separation comes into the problem domain, (Thanks to ONeal pointing out the domain belongs to the packaging system) one can try to figure out how to resolve it. There are so many kinds of programming styles, to me, because I have spent so much time on programming C++, so any small convenient accumulates to a big convenient. Write implementation along with the declaration is one of the convenient. I guess I can reduce the source lines by at least 10% if I need not to separate them. You may ask, if convenient is so important, why not just use Java? It's obviously that C++ is different with Java, they are not interchangeable.
inline function maybe resolve the problem, but it changes the semantics at all.

With this question, you're bringing up a fundamental shortcoming of the usual C++ compilation system. But letting that asside, there seems to be something broken with your first example. Indeed, such a style, where you put all of your classes completely inline, works perfectly well. The moment you start working with templates more in-depth, it is even the only way of making things work. E.g. the boost libraries are mostly just headers, even the most involved technical details are written inline, just because it wouldn't work otherwise.
My guess is that you missed the so called header guards -- and thus got the redefinition warning.
// foo.h --------
#ifndef FOO_H
#define FOO_H
class Foo {
void bar() { ... }
};
#endif // FOO_H
This should just work fine

Where to give the default values for the optional parameters?
The header file. Default arguments are just syntactic sugar which is injected in at the call site. To give them at the definition point should not compile.
Move between inline & not inline...?
Depends on two things: A. if performance matters, and B. if you have a compiler supporting Whole Program Optimization (both GCC and MSVC++ support this (not sure about others); also called "link-time code generation"). If your compiler does not support LTCG, then you might get additional performance by putting the function in the header file, because the compiler will know more about the code in each translation unit. If performance doesn't matter, try to put as much as possible into the implementation file. This way, if you change a bit of implementation you don't need to recompile your whole codebase. On the other hand if your compiler supports LTCG then it doesn't matter even from a performance prospective, because the compiler optimizes across all translation units at once.
Do you mind to separate the headers from the classes? If possible, how will you mix them into one?
There are advantages both Java/C#/friends' package system, and there are advantages to C++'s include system. Unfortunately for C++, machines with mountains of memory have made Java/C#'s system probably better. The issue with a package system like that is that you need to be able to keep the entire program structure in memory at any given time, whereas with the include system, only a single translation unit needs to be in memory at any given time. This might not matter for the average C++ or Java programmer, but when compiling a codebase of many millions of lines of code, doing something like what C++ does would have been necessary for extremely under-spec'd machines (like those C was designed to run on in 1972). Nowadays it's not so impractical to keep the program database in memory though, so this limitation no longer really applies. But we're going to be stuck with these sorts of things, at least for a while, simply because that's the way the language is structured. Perhaps a future revision of the C++ language will add a packaging system -- there's at least one proposal to do so after C++0x.
As for "mind" from a programmer prospective, I don't mind using either system, thouch C++'s seperation of the class declaration and function definition is sometimes nice because it saves an indentation level.

The first example you gave is in fact perfectly valid C++; the functions defined in the body of the class declaration are the same as if you had defined them as inline. You must have included the .h twice without some kind of include guards to make sure the compiler only saw the first copy. You may have seen this before:
#ifndef FOO_H
#define FOO_H 1
...
#endif
This ensures that if foo.h is included twice that the second copy sees that FOO_H is defined and thus skips the code.
Default parameters must be declared in the .h, not the .cc (.cpp). The reason for this is that the compiler must create a full function call with all parameters when the calling code is compiled, so it must know the value of any default parameters at the point of the call. Defining them again in the code definition is redundant and generally treated as an error.

Related

Is it safe to use #ifdef guards on C++ class member functions?

Suppose you have the following definition of a C++ class:
class A {
// Methods
#ifdef X
// Hidden methods in some translation units
#endif
};
Is this a violation of One Definition Rule for the class? What are the associated hazards?
I suspect if member function pointers or virtual functions are used this will most likely break. Otherwise is it safe to use?
I am considering it in the context of Objective C++. The header file is included in both pure C++ and Objective C++ translation units. My idea is to guard methods with Objective-C types with OBJC macro. Otherwise, I have to use void pointer for all Objective-C types in the header, but this way I am losing strong typing and also ugly static casts must be added all over the code.
Yes, it MAY allow a hazard of ODR breach if separate compilation units are allowed to have different state of macro definition X. X should be defined (or not defined) globally across program (and shared objects) before every inclusion of that class definition for program to meet requirement to be compliant. As far as C++ compiler (not preprocessor) concerned, those are two different, incompatible, unrelated class types.
Imagine situation where in compilation unit A.cpp X was defined before class A and in unit B.cpp X was not defined. You would not get any compiler errors if nothing within B.cpp uses those members which were "removed". Both units may be considered well-formed on their own. Now if B.cpp would contain a new expression, it would create an object of incompatible type, smaller than one defined in A.cpp. But any method from class A , including constructor, may cause an UB by accessing memory outside of object's storage when called with object created in B.cpp, because they use the larger definition.
There is a variation of this folly, an inclusion of header file's copy into two or more different folders of build tree with same name of file and POD struct type, one of those folders accessible by #include <filename>. Units with #include "filename" designed to use alternatives. But they wouldn't. Because order of header file lookup in this case is platform-defined, programmer isn't entirely in control of which header would be included in which unit on every platform with #include "filename". As soon as one definition would be changed, even just by re-ordering members, ODR was breached.
To be particularly safe, such things should be done only in compiler domain by using templates, PIMPL, etc. For inter-language communication some middle ground should be arranged, using wrappers or adapters, C++ and ObjectiveC++ may have incompatible memory layout of non-POD objects.
This blows up horribly. Do not do this. Example with gcc:
Header file:
// a.h
class Foo
{
public:
Foo() { ; }
#ifdef A
virtual void IsCalled();
#endif
virtual void NotCalled();
};
First C++ File:
// a1.cpp
#include <iostream>
#include "a.h"
void Foo::NotCalled()
{
std::cout << "This function is never called" << std::endl;
}
extern Foo* getFoo();
extern void IsCalled(Foo *f);
int main()
{
Foo* f = getFoo();
IsCalled(f);
}
Second C++ file:
// a2.cpp
#define A
#include "a.h"
#include <iostream>
void Foo::IsCalled(void)
{
std::cout << "We call this function, but ...?!" << std::endl;
}
void IsCalled(Foo *f)
{
f->IsCalled();
}
Foo* getFoo()
{
return new Foo();
}
Result:
This function is never called
Oops! The code called virtual function IsCalled and we dispatched to NotCalled because the two translation units disagreed on which entry was where in the class virtual function table.
What went wrong here? We violated ODR. So now two translations units disagree on what is supposed to be where in the virtual function table. So if we create a class in one translation unit and call a virtual function in it from another translation unit, we may call the wrong virtual function. Oopsie whoopsie!
Please do not deliberately do thigs that the relevant standards say are not allowed and will not work. You will never be able to think of every possible way it can go wrong. This kind of reasoning has caused many disasters over my decades of programming and I really wish people would stop deliberately and intentionally creating potential disasters.
Is it safe to use #ifdef guards on C++ class member functions?
In practice (look at the generated assembler code using GCC as g++ -O2 -fverbose-asm -S) what you propose to do is safe. In theory it should not be.
However, there is another practical approach (used in Qt and FLTK). Use some naming conventions in your "hidden" methods (e.g. document that all of them should have dontuse in their name like int dontuseme(void)), and write your GCC plugin to warn against them at compile time. Or just use some clever grep(1) in your build process (e.g. in your Makefile)
Alternatively, your GCC plugin may implement new #pragma-s or function attributes, and could warn against misuse of such functions.
Of course, you can also use (cleverly) private: and most importantly, generate C++ code (with a generator like SWIG) in your build procedure.
So practically speaking, your #ifdef guards may be useless. And I am not sure they make the C++ code more readable.
If performance matters (with GCC), use the -flto -O2 flags at both compile and link time.
See also GNU autoconf -which uses similar preprocessor based approaches.
Or use some other preprocessor or C++ code generator (GNU m4, GPP, your own one made with ANTLR or GNU bison) to generate some C++ code. Like Qt does with its moc.
So my opinion is that what you want to do is useless. Your unstated goals can be achieved in many other ways. For example, generating "random" looking C++ identifiers (or C identifiers, or ObjectiveC++ names, etc....) like _5yQcFbU0s (this is done in RefPerSys) - the accidental collision of names is then very improbable.
In a comment you state:
Otherwise, I have to use void* for all Objective-C types in the header, but this way I am losing strong typing
No, you can generate some inline C++ functions (that would use reinterpret_cast) to gain again that strong typing. Qt does so! FLTK or FOX or GTKmm also generate C++ code (since GUI code is easy to generate).
My idea was to guard methods with Objective-C types with OBJC macro
This make perfect sense if you generate some C++ or C or Objective C code with these macros.
I suspect if member function pointers or virtual functions are used this will most likely break.
In practice, it won't break if you generate random looking C++ identifiers. Or just if you document naming conventions (like GNU bison or ANTLR does) in generated C++ code (or in generated Objective C++, or in generated C, ... code)
Please notice that compilers like GCC use today (in 2021, internally) several C++ code generators. So generating C++ code is a common practice. In practice, the risks of name collisions are small if you take care of generating "random" identifiers (you could store them in some sqlite database at build time).
also ugly static casts must be added all over the code
These casts don't matter if the ugly code is generated.
As examples, RPCGEN and SWIG -or Bisoncpp- generate ugly C and C++ code which works very well (and perhaps also some proprietary ASN.1 or JSON or HTTP or SMTP or XML related in-house code generators).
The header file is included in both pure C++ and Objective C++ translation units.
An alternative approach is to generate two different header files...
one for C++, and another for Objective C++. The SWIG tool could be inspirational. Of course your (C or C++ or Objective C) code generators would emit random looking identifiers.... Like I do in both Bismon (generating random looking C names like moduleinit_9oXtCgAbkqv_4y1xhhF5Nhz_BM) and RefPerSys (generating random looking C++ names like rpsapply_61pgHb5KRq600RLnKD ...); in both systems accidental name collision is very improbable.
Of course, in principle, using #ifdef guards is not safe, as explained in this answer.
PS. A few years ago I did work on GCC MELT which generated millions of lines of C++ code for some old versions of the GCC compiler. Today -in 2021- you practically could use asmjit or libgccjit to generate machine code more directly. Partial evaluation is then a good conceptual framework.

How much is reduction in compile time if move very simple definition of function to .cpp?

I have been told by some colleagues (who are smart than me) that moving implementation (definition) outside header can reduce compile time in some cases - I should do it in most case.
After a lot of refactoring, I believe it is true.
Now I plan to move implementation of very simple functions too. (.h -> .cpp)
void f(int index){
return database[index*2]; //<--- contain trivial algorithm like this
}
Question
What are the factors to determine how much the benefit?
More specifically :-
Does the amount of time used to compile saved depends on
amount of characters (exclude comment) I moved to .cpp or ...
complexity (not mean O(n) here) of algorithm of function or ...
something else ?
Should I move definition of such simple functions to .cpp?
(concern only performance and compile time, not concern maintainability or readability)
Edit: detailed example
Consider this code.
B.h :-
class B{
public: static void fb(){
//some complex code (e.g. 1000 lines)
}
};
C.h :-
#include "B.h"
class C{
static void fc();
};
C.cpp contains implementation of fc()
D.h :-
#include "B.h"
class D{
static void fd();
};
D.cpp contains implementation of fd()
Before moving definition of fb, the compiler will have to compile large code of B.h for C.cpp and D.cpp.
After moving definition of fb to b.cpp, I think C.cpp and D.cpp will be a lot easier to compile.
What are the factors to determine how much the benefit?
The major factor for reduction of compile time depends on how many other translation units include that header with the inlined code. The other factors you mentioned are merely irrelevant.
If you change something in the definition many more files would need to be recompiled, than if you change the definition only in a single .cpp file.
Should I move definition of such simple functions to .cpp?
(concern only performance and compile time, not concern maintainability or readability)
No, what I said above refers to non trivial stuff. If you have such simple function definition and it's unlikely it will be changed in future, you can leave it in the header file.
The answer can be simple and less simple.
Simple answer:
put implementation of non-trivial function in the source files, there are many advantages to this, not just compilation time.
Leave implementation of trivial function in the header file and make non-member-functions inline, the compilation time will not differ significantly and there are even better optimization possibilities.
Less simple:
Putting non-trivial functions in source file is done specifically so the header files, which are like interfaces to the code, are more readable, don't have to contain all the includes needed for implementation, can prevent mutual cycle issues and on top have better compilation times.
Putting trivial functions in the header file let the compiler do better optimisation during compile-time (as opposed to link-time) because it knows at the calling point what the function does, so it knows better when to inline and reorder code (see here for link-time optimization).
Templates should still always be in header files. for some complex functions, the non-template part may be factored out and put in a source file, but this can be fiddly.
For encapsulation reasons, it may be better to declare helper functions and helper classes in the source file completely.
When using pimpl-constructs, the trivial delegation functions, must be in the source file because only there, the pimpl is fully known.
So in the end ordering the code can cause better compilation times, but that shouldn't be the main reason.
If you call this function which's body is in .h , it will get reference to your #include's in order to find it, because #include gives only a reference.
It will be easier for the compiler if your function's body is in .cpp
I suggest you check this out. It helped me too.
What techniques can be used to speed up C++ compilation times?

A "source-less" C++ idiom

I am developing a fairly large C++ support library, and have found myself moving towards a header-only approach. In C++ this almost works because you can implement where you define in classes. For templated methods, the implementation has to be in the same file anyway, so I find that it is much easier to just keep the implementation with the definition.
However, there are several times where "sources" must be used. As just one example, circular dependencies sometimes occur and the implementation has to be written outside the class definition. Here is how I am handling it:
//part of libfoo.h
class Bar
{
void CircularDependency(void);
};
#ifdef LIBFOO_COMPILE_INLINE
void Bar::CircularDependency(void)
{
//...
}
#endif
Then the project that uses libfoo would do the following in main.cpp:
//main.cpp
#define LIBFOO_COMPILE_INLINE
#include "libfoo.h"
And in any other .cpp:
//other.cpp
#include "libfoo.h"
The point is that the compile-inline section only gets compiled once (in main.cpp).
And finally my question: is there a name for this idiom or any other projects that work this way? It just seems to be a natural outcome of the implementation and definition being blurred by templating and class methods. And: are there any reasons why this is a bad idea or why it would potentially not scale well?
Quick aside: I know that many coders, with good reason, prefer their headers to resemble interfaces and not implementations, but IMHO documentation generators are better suited to describing interfaces because I like to hide private members all together :-)
You should be able to use the inline keyword if the circular dependency problem is resolved by the time the definition of Bar::CircularDependency() would show up in the libfoo.h header:
//part of libfoo.h
class Bar
{
void CircularDependency(void);
};
// other stuff that 'resolves' the circular dependency
// ...
// ...
inline void Bar::CircularDependency(void)
{
//...
}
That would make your library easier to use (the user wouldn't need to deal with the fact that LIBFOO_COMPILE_INLINE needed to be defined in exactly one place where the header is included).
Circular dependencies are not really a problem as you can forward decalre that functions are inline. I wouldn't really suggest this, though: while the "source-less" approach initially makes it easier to use a library coming from somewhere, it causes longer compile times and tighter coupling between files. In a huge source base this is essentially killing the hOpe to get code build in reasonable times. Sure huge only starts at a couple millions lines of code but who cares about trivial programs...? (and, yes, the place I work at has several tens of millions lines of code being build into single executables)
My reasons for why this is a bad idea.
Increase in compile time
Every individual compilation unit that includes the header should compile all the header files in addition to the source in itself. This would probably increase the compile time and might be frustrating while testing your code, with small changes. One could argue the compiler might optimize it, but IMO it could not optimize it beyond a point.
Bigger code segment
If all the functions are written inline, it means that the compiler has to put all that code wherever the function is called. This is going to blow up the code segment and it would affect the load time of the program and the program would take more memory.
Creates dependency in client code with tight coupling
Whenever you change your implementation, every client should get updated (by re compiling the code). But if the implementation has been put in an independent shared object (.so or .dll), the client should just link to the new shared object.
Also I am not sure why one would do this.
//main.cpp
#define LIBFOO_COMPILE_INLINE
#include "libfoo.h"
If at all one has to do this, (s)he could have simply put the implementation code in main.cpp itself. Anyway, you could define LIBFOO_COMPILE_INLINE only in one compilation unit. Otherwise you will duplicate definitions.
I am actually much interested in developing a idiom to write cohesive template code. Sometime in future, C++ compiler should support writing cohesive templates. By this, I mean the client need not have to recompile the code, whenever template implementation in modified.

One class with multiple implementation files

Is there anything wrong with having a single class (one .h) implemented over multiple source files? I realize that this could be a symptom of too much code in a single class, but is there anything technically wrong with it?
For instance:
Foo.h
class Foo
{
void Read();
void Write();
void Run();
}
Foo.Read.cpp
#include "Foo.h"
void Foo::Read()
{
}
Foo.Write.cpp
#include "Foo.h"
void Foo::Write()
{
}
Foo.Run.cpp
#include "Foo.h"
void Foo::Run()
{
}
This is fine. In the end, it will be all linked together.
I have even seen code, where every member function was in a different *.cpp file.
That is legitimate and it has some (!?) advantages...
If you link your executable with the static library of this class, only the used functions will get in. This is very handy for limited-resource systems.
You can also hide implementation details of certain functions. Two people may implement parts of a class without knowing about each other. Handy for DOD projects.
If you look at any CRT source, you will see the same pattern...
Nope, nothing technically wrong with it. The linker will bring all the pieces of Foo together in the final binary.
I've been working with the Apache Portable Runtime, which does pretty much this exact thing. You have a header, say apr_client.h and multiple implementation files for the functions in that header -- each file representing one aspect of client operations. It's not wrong, and it's not really unusual.
this could be a symptom of too much code in a single class
C++ is not Java, so you don't have to pick your file names according to your class names.
It is perfectly valid. All cpp files will be linked together.
This can be useful for, as you said, making a very large implementation file more readable and, since each cpp file is a compilation unit, you could (ab)use that fact. (Unnamed namespaces for example)
yea thats legitmate, and in fact newer languages like C# do that sort of thing of all the time.
There are two points which may be worth considering.
Class wide optimisations:
If the compiler has all of the member functions visible to it when its parsing the file (assuming a single TU compiler) then it may be able to perform optimisations between the different member functions.
Code Review
If all the definitions for a class are in the same TU, then this makes manual code review easier. If the definitions are split into different TUs, this significantly increases the effort required for a manual review as the appropriate files need to be searched for, with constant flicking between windows to get the "whole" picture.

Is it worth forward-declaring library classes?

I've just started learning Qt, using their tutorial. I'm currently on tutorial 7, where we've made a new LCDRange class. The implementation of LCDRange (the .cpp file) uses the Qt QSlider class, so in the .cpp file is
#include <QSlider>
but in the header is a forward declaration:
class QSlider;
According to Qt,
This is another classic trick, but one that's much less used often. Because we don't need QSlider in the interface of the class, only in the implementation, we use a forward declaration of the class in the header file and include the header file for QSlider in the .cpp file.
This makes the compilation of big projects much faster, because the compiler usually spends most of its time parsing header files, not the actual source code. This trick alone can often speed up compilations by a factor of two or more.
Is this worth doing? It seems to make sense, but it's one more thing to keep track of - I feel it would be much simpler just to include everything in the header file.
Absolutely. The C/C++ build model is ...ahem... an anachronism (to say the best). For large projects it becomes a serious PITA.
As Neil notes correctly, this should not be the default approach for your class design, don't go out of your way unless you really need to.
Breaking Circular include references is the one reason where you have to use forward declarations.
// a.h
#include "b.h"
struct A { B * a; }
// b.h
#include "a.h" // circlular include reference
struct B { A * a; }
// Solution: break circular reference by forward delcaration of B or A
Reducing rebuild time - Imagine the following code
// foo.h
#include <qslider>
class Foo
{
QSlider * someSlider;
}
now every .cpp file that directly or indirectly pulls in Foo.h also pulls in QSlider.h and all of its dependencies. That may be hundreds of .cpp files! (Precompiled headers help a bit - and sometimes a lot - but they turn disk/CPU pressure in memory/disk pressure, and thus are soon hitting the "next" limit)
If the header requires only a reference declaration, this dependency can often be limited to a few files, e.g. foo.cpp.
Reducing incremental build time - The effect is even more pronounced, when dealing with your own (rather than stable library) headers. Imagine you have
// bar.h
#include "foo.h"
class Bar
{
Foo * kungFoo;
// ...
}
Now if most of your .cpp's need to pull in bar.h, they also indirectly pull in foo.h. Thus, every change of foo.h triggers build of all these .cpp files (which might not even need to know Foo!). If bar.h uses a forward declaration for Foo instead, the dependency on foo.h is limited to bar.cpp:
// bar.h
class Foo;
class Bar
{
Foo * kungFoo;
// ...
}
// bar.cpp
#include "bar.h"
#include "foo.h"
// ...
It is so common that it is a pattern - the PIMPL pattern. It's use is two-fold: first it provides true interface/implementation isolation, the other is reducing build dependencies. In practice, I'd weight their usefulness 50:50.
You need a reference in the header, you can't have a direct instantiation of the dependent type. This limits the cases where forward declarations can be applied. If you do it explicitely, it is common to use a utility class (such as boost::scoped_ptr) for that.
Is Build Time worth it? Definitely, I'd say. In the worst case build time grows polynomial with the number of files in the project. other techniques - like faster machines and parallel builds - can provide only percentage gains.
The faster the build, the more often developers test what they did, the more often unit tests run, the faster build breaks can be found fixed, and less often developers end up procrastinating.
In practice, managing your build time, while essential on a large project (say, hundreds of source files), it still makes a "comfort difference" on small projects. Also, adding improvements after the fact is often an exercise in patience, as a single fix might shave off only seconds (or less) of a 40 minute build.
I use it all the time. My rule is if it doesn't need the header, then i put a forward declaration ("use headers if you must, use forward declarations if you can"). The only thing that sucks is that i need to know how the class was declared (struct/class, maybe if it is a template i need its parameters, ...). But in the vast majority of times, it just comes down to "class Slider;" or something along that. If something requires some more hassle to be just declared, one can always declare a special forward declare header like the Standard does with iosfwd too.
Not including the header file will not only reduce compile time but also will avoid polluting the namespace. Files including the header will thank you for including as little as possible so they can keep using a clean environment.
This is the rough plan:
/* --- --- --- Y.hpp */
class X;
class Y {
X *x;
};
/* --- --- --- Y.cpp */
#include <x.hpp>
#include <y.hpp>
...
There are smart pointers that are specifically designed to work with pointers to incomplete types. One very well known one is boost::shared_ptr.
Yes, it sure does help. Another thing to add to your repertoire is precompiled headers if you are worried about compilation time.
Look up FAQ 39.12 and 39.13
The standard library does this for some of the iostream classes in the standard header <iosfwd>. However, it is not a generally applicable technique - notice there are no such headers for the other standard library types, and it should not (IMHO) be your default approach to designing class heirarchies.
Although this eems to be a favourite "optimisation" for programmers, I suspect that like most optimisations, few of them have actually timed the build of their projects both with and without such declarations. My limited experiments in this area indicate that the use of pre-compiled headers in modern compilers makes it unecessary.
There is a HUGE difference in compile times for larger projects, even ones with carefully managed dependencies. You better get the habit of forward declaring and keep as much as possible out of header files, because at a lot of software shops which uses C++ it's required. The reason for why you don't see it all that much in the standard header files is because those make heavy use of templates, at which point forward declaring becomes hard. For MSVC you can use /P to take a look at how the preprocessed file looks before actual compilation. If you haven't done any forward declaration in your project it would probably be an interesting experience to see how much extra processing needs to be done.
In general, no.
I used to forward declare as much as I could, but no longer.
As far as Qt is concerned, you may notice that there is a <QtGui> include file that will pull in all the GUI Widgets. Also, there is a <QtCore>, <QtWebKit>, <QtNetwork> etc. There's a header file for each module. It seems the Qt team believes this is the preferred method also. They say so in their module documentation.
True, the compilation time may be increased. But in my experience its just not that much. And if it were, using precompiled headers would be the next step.
When you write ...
include "foo.h"
... you thereby instruct a conventional build system "Any time there is any change whatsover in the library file foo.h, discard this compilation unit and rebuild it, even if all that happened to foo.h was the addition of a comment, or the addition of a comment to some file which foo.h includes; even if all that happened was some ultra-fastidious colleague re-balanced the curly braces; even if nothing happened other than a pressured colleague checked in foo.h unchanged and inadvertently changed its timestamp."
Why would you want to issue such a command? Library headers, because in general they have more human readers than application headers, have a special vulnerability to changes that have no impact on the binary, such as improved documentation of functions and arguments or the bump of a version number or copyright date.
The C++ rules allow namespace to be re-opened at any point in a compilation unit (unlike a struct or class) in order to support forward declaration.
Forward declarations are very useful for breaking the circular dependencies, and sometimes may be ok to use with your own code, but using them with library code may break the program on another platform or with other versions of the library (this will happen even with your code if you're not careful enough). IMHO not worth it.