forward declaration of classes, splitting variables and functions [duplicate] - c++

This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed 9 years ago.
Do you have any good advice on how to avoid circular dependencies of header files, please?
Of course, from the beginning, I try to design the project as transparent as possible. However, as more and more features and classes are added, and the project gets less transparent, circular dependencies start happening.
Are there any general, verified, and working rules? Thanks.

If you have circular dependency then you doing something wrong.
As for example:
foo.h
-----
class foo {
public:
bar b;
};
bar.h
-----
class bar {
public:
foo f;
};
Is illegal you probably want:
foo.h
-----
class bar; // forward declaration
class foo {
...
bar *b;
...
};
bar.h
-----
class foo; // forward declaration
class bar {
...
foo *f;
...
};
And this is ok.
General rules:
Make sure each header can be included on its own.
If you can use forward declarations use them!

Use forward declarations where possible.
Move any header includes out of a header file and into the corresponding cpp file if they are only needed by the cpp file. Easiest way to enforce this is to make the #include "myclass.h" the first include in myclass.cpp.
Introducing interfaces at the point of interaction between separate classes can help reduce dependencies.

Some best practices I follow to avoid circular dependencies are,
Stick to OOAD principles. Don't include a header file, unless the class included is in composition relationship with the current class. Use forward declaration instead.
Design abstract classes to act as interfaces for two classes. Make the interaction of the classes through that interface.

A general approach is to factor out the commonalities into a third header file which is then referenced by the two original header files.
See also Circular Dependency Best Practice

depending on your preprocessor capabilities:
#pragma once
or
#ifndef MY_HEADER_H
#define MY_HEADER_H
your header file
#endif
If you find it very boring to design header files maybe makeheaders from Hwaci (designers of SQLite and fossil DVCS) could be of interest for you.

What you're aiming at is a layered approach. You can define layers where modules can depend on lower layer modules but the inverse should be done with observers. Now you can still define how fine-grained your layers should be and whether you accept circular dependency within layers, but in this case I would use this.

In general header files should forwardly declare rather than include other headers wherever possible.
Also ensure you stick to one class per header.
Then you almost certainly will not go wrong.
The worst coupling usually comes from bloated template code. Because you have to include the definition inside the header, it often leads to all kinds headers having to be included, and then the class that uses the template includes the template header, including a load of other stuff.
For this reason, I would generally say: be careful with templates! Ideally a template should not have to include anything in its implementation code.

Altough Artyom provided best answer this tutorial is also great and provides some extenstions http://www.cplusplus.com/forum/articles/10627/

Related

How to avoid include files spreading due to template classes

Due to the implementation of a template class in a header file, I have to include the other includes used in the implementation of the class in the header file.
Because of that, each time I include my template class that bring all other the inclusions and so on.
This could bring to an eccessive spread of inclusion, or even unnecessary for the context.
So what's the best way to deal with this issue?
Edit: Since I've not explictely mentioned it, I'm not talking about cases where forward declaration could solve it like in a normal .h/.cpp separation, but when you have to include the header, and since you don't have the cpp, you are force to use it in .h
Edit 2: Let's say my template class has a function with a dependency with a third class library. Each class using my template class now has the same depency, or can access to that header which both I could not want to. Does it exists a way to avoid that?
Use forward declaration where ever appropriate instead of #include.
Header file should #include only the needed and rest should go in source file.

Avoiding Circular Dependencies of header files [duplicate]

This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed 9 years ago.
Do you have any good advice on how to avoid circular dependencies of header files, please?
Of course, from the beginning, I try to design the project as transparent as possible. However, as more and more features and classes are added, and the project gets less transparent, circular dependencies start happening.
Are there any general, verified, and working rules? Thanks.
If you have circular dependency then you doing something wrong.
As for example:
foo.h
-----
class foo {
public:
bar b;
};
bar.h
-----
class bar {
public:
foo f;
};
Is illegal you probably want:
foo.h
-----
class bar; // forward declaration
class foo {
...
bar *b;
...
};
bar.h
-----
class foo; // forward declaration
class bar {
...
foo *f;
...
};
And this is ok.
General rules:
Make sure each header can be included on its own.
If you can use forward declarations use them!
Use forward declarations where possible.
Move any header includes out of a header file and into the corresponding cpp file if they are only needed by the cpp file. Easiest way to enforce this is to make the #include "myclass.h" the first include in myclass.cpp.
Introducing interfaces at the point of interaction between separate classes can help reduce dependencies.
Some best practices I follow to avoid circular dependencies are,
Stick to OOAD principles. Don't include a header file, unless the class included is in composition relationship with the current class. Use forward declaration instead.
Design abstract classes to act as interfaces for two classes. Make the interaction of the classes through that interface.
A general approach is to factor out the commonalities into a third header file which is then referenced by the two original header files.
See also Circular Dependency Best Practice
depending on your preprocessor capabilities:
#pragma once
or
#ifndef MY_HEADER_H
#define MY_HEADER_H
your header file
#endif
If you find it very boring to design header files maybe makeheaders from Hwaci (designers of SQLite and fossil DVCS) could be of interest for you.
What you're aiming at is a layered approach. You can define layers where modules can depend on lower layer modules but the inverse should be done with observers. Now you can still define how fine-grained your layers should be and whether you accept circular dependency within layers, but in this case I would use this.
In general header files should forwardly declare rather than include other headers wherever possible.
Also ensure you stick to one class per header.
Then you almost certainly will not go wrong.
The worst coupling usually comes from bloated template code. Because you have to include the definition inside the header, it often leads to all kinds headers having to be included, and then the class that uses the template includes the template header, including a load of other stuff.
For this reason, I would generally say: be careful with templates! Ideally a template should not have to include anything in its implementation code.
Altough Artyom provided best answer this tutorial is also great and provides some extenstions http://www.cplusplus.com/forum/articles/10627/

Is it possible to define a class in 2 or more file in C++?

I know it's possible to do class implementation in more than one file(yes, I know that this is bad idea), but I want to know if it's possible to write class definition in separate files without getting a redefinition error (maybe some tricks, or else...)
No, not the same class, but why would you?
You could define two classes with the same name in the same namespace (the same signature! That will actually be the same class at all, just defined in two ways) in two different header files and compile your program, if your source files don't include both headers. Your application could even be linked, but then at runtime things won't work as you expect (it'll be undefined behavior!), unless the classes are identical.
See Charles Bailey's answer for a more formal explanation.
EDIT:
If what you want is to have a single class defined by more than one file, in order to (for example) add some automatically generated functions to your class, you could #include a secondary file in the middle of your class.
/* automatically generated file - autofile.gen.h */
void f1( ) { /* ... */ }
void f2( ) { /* ... */ }
void f3( ) { /* ... */ }
/* ... */
/* your header file with your class to be expanded */
class C
{
/* ... */
#include "autofile.gen.h"
/* ... */
};
Not as nice and clean as the partial keyword in C#, but yes, you can split your class into multiple header files:
class MyClass
{
#include "my_class_aspect1.h"
#include "my_class_aspect2.h"
#include "my_class_aspect3.h"
};
#include "my_class_aspect1.inl"
#include "my_class_aspect2.inl"
#include "my_class_aspect3.inl"
Well sort of ...
If you have 1 header file as follows
ClassDef1.h:
class ClassDef
{
protected:
// blah, etc.
public:
// more blah
and another as follows
ClassDef2.h:
public:
// Yet more blah.
};
The class will effectively have been defined across 2 files.
Beyond that sort of trickery .. AFAIK, no you can't.
Yes, you can. Each definition must occur in a separate translation unit but there are heavy restrictions on multiple definitions.
Each definition must consist of the same sequence of tokens and in each definition corresponding names must refer to the same entity (or an entity within the definition of the class itself).
See 3.2 [basic.def.odr] / 5 of ISO 14882:2003 for full details.
Yes. Usually, people put the declaration part in .h file and then put the function body implementations in .cpp file
Put the declarations in a .h file, then implement in as many files as you want, but include the .h in each.
But, you cannot implement the same thing in more than one file
I know this is a late post, but a friend just asked me a similar question, so I thought I would post our discussion:
From what I understand you want to do ThinkingStiff, it's not possible in C++. I take it you want something like "partial class" in C#.
Keep in mind, "partial class" in .NET is necessary so you don't have to put your entire implementation in one big source file. Unlike C++, .NET does not allow your implementation to be separate from the declaration, therefore the need for "partial class". So, Rafid it's not a nice feature, it's a necessary one, and a reinvention of the wheel IMHO.
If your class definition is so large you need to split it across more than one source file, then it can probably be split into smaller, decoupled classes and the primary class can use the mediator design pattern that ties them all together.
If your desire is to hide private members, such as when developing a commercial library and you don't wish to give away intelectual property (or hints to that affect), then you can use pure abstract classes. This way, all that is in the header is simple class with all the public definitions (API) and a factory function for creating an instance of it. All the implementation details are in your source file(s).
Another alternative is similar to the above, but uses a normal class (not a pure virtual one), but still exposes only the public interface. In your source file(s), you do all the work inside a nameless namespace, which can include friend functions from your class definition when necessary, etc. A bit more work, but a reasonable technique.
I bolded those things you might want to lookup and consider when solving your problem.
This is one of the nice features of C#, but unfortunately it is not supported in C++.
Perhaps something like policy based design would do the trick? Multiple Inheritience gives you the possiblity to compose classes in ways you can't in other languages. of course there are gotchas associated with MI so make sure you know what you are doing.
The short answer is yes, it is possible. The correct answer is no, you should never even think about doing it (and you will be flogged by other programmers should you disregard that directive).
You can split the definitions of the member functions into other translation units, but not of the class itself. To do that, you'd need to do preprocessor trickery.
// header file with function declarations
class C {
public:
void f(int foo, int bar);
int g();
};
// this goes into a seperate file
void C::f(int foo, int bar) {
// code ...
}
// this in yet another
void C::g() {
// code ...
}
There must be a reason why you want to split between two headers, so my guess is that you really want 2 classes that are joined together to form components of a single (3rd) class.

Forward Declarations and Includes

When working with a library, whether it be my own or external, there are lot of classes with forward declarations. The same classes also have includes as well depending on the situation. When I use a certain class, I need to know whether certain objects that the class uses, are forward declared or are they #include(d). The reason is I want to know whether I should be including both headers or just one.
Now I know it is fairly simple to check, just compile (or go through all the headers until you find the object in question either #include(d) or forward declared). But with large projects, a simple compile takes a long time, and going into each include file to check whether the class in question is being included or forward declared is tedious, especially if it is a few levels deep. To illustrate the problem further:
Class A is a Class B is a Class C
which has a pointer to Class Foo
I include Class A and want to know whether Class Foo is ready for use right away, or whether I have to do the following:
#include "ClassA.h"
#include "ClassFoo.h"
So, is there a quick and easy way to find out about this dependency without compiling or going into the depended headers? (one of the reasons I ask this question is because I want to eventually make an add-in for VS and/or stand-alone program for this if the functionality does not already exist)
Thanks!
In a source file you should not depend on what the other header files include.
You should explicitly include every type that your code depends on.
If you do not use a type (ie just passing a pointer or a reference around) then you don't need its definition so don't include its header file (The header file for the methods you are using should have at least a forwward declaration).
So in your particular instance it is hard to tell.
Is you source file explicitly uses any members from Foo then you need to include "ClassFoo.h" otherwise don't. There is no need to go digging around in header files (they may change anyway). Just check exactly what your source file uses and include those (and only those) header files.
In the header file: Prefer forward declaration to inclusion. This way you limit/break circular dependencies.
Actually I am finding eliminating as many header includes as is humanly possible actually helps hella more. See this answer. By cutting out more #include statements, its much more clear exactly what is part of the source file (#includes are a blackbox - you never know what is getting linked in by that one line of text). If a class Foo needs the implementation details of a class Bar, then Foo.h should not include "Bar.h", but rather, contain only a forward declaration. Foo.cpp should include Bar.h.
Foo.h
class Bar ; // fwd declare wherever possible
class Foo
{
// I can haz needs Bar
void do( Bar *bar ) ;
} ;
Foo.cpp
#include "Foo.h"
#include "Bar.h" // I can has needs complete implementation details.
Foo::do( Bar *bar )
{
}
Bar.h
class Bar
{
// code..
} ;
If you're using class A then you should only care about the private interface of the base class C (and possibly additional interface in A. If the class is designed properly, you won't need to access Foo directly because it will be encapsulated in C's interface and not exposed to the public world. In this case you won't need an include to Foo at all because it's not part of C's public interface. If in fact Foo is part of the interface to C in some way, then I argue that C.h should include Foo.h as well, so that clients can use it without having to make the determinations you're asking about.

Forward declaration in multiple source directory; template instantation

I am looking for a nice book, reference material which deals with forward declaration of classes esp. when sources are in multiple directories, eg. class A in dirA is forward declared in class B in dirB ? How is this done ?
Also, any material for template issues, advanced uses and instantation problems, highly appreicated ?
Thanks.
Forward declarations have nothing to do with the directory structure of your project. You can forward declare something even not existing in your project. They are mostly used to resolve cyclic references between classes and to speed up compilation when the complete class declaration is not necessary, and the corresponding #include can be replaced with a forward declaration.
To determine when a forward declaration is sufficient, the sizeof() query can usually answer the question. For example,
class Wheel;
class Car
{
Wheel wheels[4];
};
In this declaration, a forward declaration cannot be used since the compiler cannot determine the size of a Car: it doesn't know how much data the wheels contain. In other words, sizeof(Car) is unknown.
Also regarding templates, forward declared classes cannot be used as template parameters if the template class contains data members of the template parameter (but their pointers can be). For instance,
template<class T> class pointer
{
T *ptr;
};
class Test;
pointer<Test> testpointer;
is legal but
std::vector<Test> testvector will not compile.
Because of the aforementioned limitations, forward declared classes are generally used as pointers or references.
I don't know if there's a book on the subject but you can see this section on c++ faq lite.
Generally speaking you can forward declare in headers as a means of avoiding full includes or as a way to enable circular referencing (bad).
You can use a forward declared type by pointer or reference or return type only.
Large-Scale C++ Software Design by John Lakos (book review here) addresses physical design (files) and logical design and how they relate to software components (which aren't always 1:1 with classes).
if they are in parallel directories you can include it like
#include "../dirB/B.h"
but in header you just call this line for forward decleration
class B;
instead of this, you can seperate your include directories and source directories.
so then you can show include directory as this directory and you can add header by calling
#include "dirB/B.h"
since you will make a forward decleration on header, it wont be problem.