I have a set of classes to implement and I plan to do it in the following way:
(1) A master header file (entity.h) that has all the forward declarations of these classes enclosed in a namespace i.e.:
namespace SomeNameSpace {
class A;
...
class E;
}
(2) Each of the classes then have separate header files (i.e. A.h, B.h) that defines the classes and declares all the constituent variables and methods.
(3) And finally, the .cpp's that define all the members and statics (i.e. A.cpp, B.cpp).
Now, I tried to put this scheme to work by doing #include "entity.h", but I am slapped with an "ambiguity" error whenever I try to use one of these classes. If I skip step (1) and simply include all the individuals header files of each class, then I don't have that problem (and that's how I've been writing code).
So anyway, is my scheme viable? Is there some way to make it work? What I really wanted is to have some sort of way to put every custom object in one namespace. I suppose I can make that work by simply putting all the class declarations into one file, but that'd make entity.h bloated.
I've searched around with keywords "forward declaration", "C++", "namespace", "one namespace", "master header", "header" and couldn't find anything that's quite relevant. Maybe what I want to do is wrong?
You cannot use "class A;" in your entity.h because that means that you are actually declaring a class but you already have done so in A.h
You can either add the whole declaration in your entity.h but not using any A.h, B.h etc.
Or, you can just use the same namespace in each *.h file :
A.h ->
namespace SomeNamespace {
class A ...
}
B.h ->
namespace SomeNamespace{
class B ...
}
A different approach would be wrapping the classes into a namespace directly from the original headers, and then including them, e.g.:
A.h:
namespace SomeNameSpace {
class A{
// Class definition
void something();
}
}
A.cpp:
#include "A.h"
namespace SomeNameSpace {
void A::something()
{
}
// And other function definitions
}
entity.h:
#include "A.h"
#include "B.h"
// And so on...
You cannot use a class in a scope where there is not a complete definition (the forward declaration is not enough). Normally you might forward declare in the header and #include in the cpp. I don't see the point in organizing the way you are trying to; The canonical wisdom is to forward declare whenever possible and #include whenever necessary.
Related
I'm trying to setup a simulation program. The simulation runs for a number of steps, and the simulation class should call ::step() of a bunch of different classes, one of them is the _experiment class.
I cannot get this to work, because the experiment class needs the simulation class and the simulation class needs to know what an experiment class is, so they are cyclic dependent. I've tried solving it by using a forward declaration, but then I cannot acces methods of the forward declared class. What is the point of forward declaring then? Can anyone help me? Thanks!
main.cpp
int main()
{
_experiment experiment;
}
experiment.cpp:
#include "experiment.h"
_experiment::experiment()
{
_simulation simulation;
simulation.experiment = this;
simulation.start();
}
void _experiment::step()
{
//Apply forces to simulation
}
experiment.h:
#include "simulation.h"
class _experiment {
public:
void step()
};
simulation.cpp:
#include "simulation.h"
void _simulation::run()
{
//Run simulation for 1000 steps
for(int i = 0; i < 1000; i++)
{
experiment->step() //Calculate forces. Doesnt work (cant use member functions of forward declared classes. How to work around this?
//Calculate motion
}
}
simulation.h:
class _experiment; //Forward declaration
class _simulation {
public:
_experiment* experiment
void run();
};
experiment.h does not need to include simulation.h, or forward declare _simulation, since the definition of _experiment doesn't depend on _simulation at all.
You already have a forward declaration or _experiment in simulation.h, which is good, since the definition of _simulation contains a pointer to _experiment, so doesn't need the full definition.
What's missing is the definitions of both classes in the source files. Include both headers from both source files, since they do need the class definitions, and everything should be good.
In general, if you include all the headers you need in source files, and only include a header from another header when you need more than a forward declaration, then you'll mostly avoid circular dependency problems.
You'll also need to add include guards to the headers, to avoid multiple definitions on those occasions when you do need to include headers from other headers.
What is the point of forward declaring then?
It allows you declare that a class exists, without having to declare anything else that the class depends on. You can do several useful things, such as define pointers or references to the class, or declare functions with the class as an argument or return type, with only a forward declaration. You just can't do anything that requires knowledge of the size or members of the class.
You don't have the definition of _experiment in simulation.cpp, include the experiment.h file in the source file and all should work.
Also, the _experiment class doesn't seem to use _simulation in your example, so no need to include simulation.h in experiment.h. Also add include guards to your header files.
I have class A (in A.h) which depends on class B in (B.h) and vice versa. Forward declaring the used functions works, but this means I have to update everywhere where I forward declared those functions in the future, ex, if I remove, or change argument in those functions they must all be updated to reflect change. I don't feel this is good practice. Is there a way around this?
Thanks
If you only need to work with pointers or references to a class at the declaration level, you can do it like this:
A.h
class B; // forward class declaration
class A {
A(B &);
};
B.h
class A;
class B {
B(A &);
};
B.cpp
#include "B.h"
#include "A.h" // now we get the full declaration of A
B::B(A &a) {
a.foo(5);
}
Mutual dependencies like this are tough to deal with but sometimes unavoidable.
If A and B depend on the implementations of each other, then you've got a system design problem that you need to resolve before proceeding further.
The best way is to have a forward declaration header:
a.fwd.h
#pragma once
class A;
a.h
#pragma once
#include "a.fwd.h"
#include "b.fwd.h"
class A
{
A(B*);
};
etc.
This way, each class provides its own forward declarations - localised alongside the header where it belongs - checked for consistency with the real declarations and definitions by including the forward declaration header in the header, and the header in the implementation.
Consider the following two scenarios (Edited just to complete the whole question and make it clearer)
Case 1: (doesnt compile as rightly mentioned below)
//B.h
#ifndef B_H
#define B_H
#include "B.h"
class A;
class B {
A obj;
public:
void printA_thruB();
};
#endif
//B.cpp
#include "B.h"
#include <iostream>
void B::printA_thruB(){
obj.printA();
}
//A.h;
#ifndef A_H
#define A_H
#include "A.h"
class A {
int a;
public:
A();
void printA();
};
#endif
//A.cpp
#include "A.h"
#include <iostream>
A::A(){
a=10;
}
void A::printA()
{
std::cout<<"A:"<<a<<std::endl;
}
//main.cpp
#include "B.h"
#include<iostream>
using namespace std;
int main()
{
B obj;
obj.printA_thruB();
}
Case 2: (the only modifications...works without compiliation error)
//B.h
#include "A.h" //Add this line
//class A; //comment out this line
Let us assume both the A.cpp and B.cpp are complied together. Do the above two scenarios make any differences? Is there a reason to prefer one method over the other?
Edit:
So how do I make scenario 1 work.
Forward declaration is not a substitute for Header file inclusion.
As the name itself implies, forward declaration is just a Declaration and not a definition.
So, you will declare saying the compiler that it is a class and I just declaring it here and will provide you the definition when am gonna use it. So, normally you forward declare in the Header file and #include in the .cpp file where you will use the members of the forward declared class.
By doing so, what you make is, wherever you are including the header file there will just be a declaration for the class instead of the entire contents #included...
But having said that, when the compiler requires the definition of the class, it should be #included..
So, in your case A obj; requires the definition of class A and hence you should #include..
I myself asked a similar question here and another similar question which has also a nice answer...
Hope it helps..
Case 1 will produce an "incomplete type" error when you compile B.cpp. Because class B contains a class A object, the definition (and in particular the size) of class A is required to be complete before the definition of class B.
Alternatively, you could choose to make some_variable a pointer or reference to class A, and in that case your forward declaration would be sufficient in B.h. You'd still need a full definition of A in B.cpp (assuming you made actual use of the A member functions/data).
You need to use forward declarations in cases where you have classes that refer to each other.
//A.h
class B;
class A {
B* someVar;
}
//B.h
#include <A.h>
class B {
A* someVar;
}
But there's no benefit for doing it in the case you laid out.
Think like a compiler. In order to create an A inside of B, the compiler has to know how to build an A, and the only way to do that is to have the complete definition. The forward declaration tells the compiler that class A exists without describing what it looks like; this is adequate for defining a pointer or a reference. When it comes time to use that pointer or reference, the complete class definition will be required.
If you meant to portray some_variable as a pointer then the frequently recommended practice is to use forward declarations whenever possible to avoid the overhead of includes and longer compile times.
I'm all for best practices but I really like using IDEs that have nice code navigation features and forwards cause a problem there, at least with Netbeans. Whenever I try to navigate to a type declaration, I always end up at the forward and not the .h file containing the actual declaration. I'm willing to accept some extra compile time for the ease of navigation. Maybe this is just a problem with Netbeans :)
.. oh yeah.. If you look at the related questions to the right of your question, you will find lots of additional information of forward declarations.
For case 1, compiler will complain with "incomplete type" for class B because class B contains a class A object, and you did not tell B any detail of class A, so compiler cann't decide the size of object B.
For your case, you can use A& obj or A* obj instead of A obj, since the size of a reference/pointer is const(4/8 for 32bit/64bit CPU).
So I have a class A, where I want to call some class B functions. So I include "b.h". But, in class B, I want to call a class A function. If I include "a.h", it ends up in an infinite loop, right? What can I do about it?
Put only member function declarations in header (.h) files, and put member function definitions in implementation (.cpp) files. Then your header files do not need to include each other, and you can include both headers in either implementation file.
For cases when you need to reference the other class in member signatures as well, you can use a forward declaration:
class A;
This lets you use pointer and reference types (A* and A&), though not A itself. It also doesn't let you call members.
Example:
// a.h
struct B; // forward declaration
struct A {
void foo(B* b); // pointers and references to forward-declared classes are ok
};
// b.h
struct A; // forward declaration
struct B {
void bar(A& a); // pointers and references to forward-declared classes are ok
};
// a.cpp
#include "a.h"
#include "b.h"
void A::foo(B* b) {
b->bar(*this); // full declaration of B visible, ok to call members now
}
// b.cpp
#include "a.h"
#include "b.h"
void B::bar(A& a) {
a.foo(this); // full declaration of A visible, ok to call members now
}
Each class (A and B) should have a header file and an implementation file.
Each header file (e.g. A.h) should not include the other header file (e.g. B.h) but may include a forward reference to the other class (e.g. a statement like class B;), and may then use pointers and/or references to the other class in its declaration (e.g. class A may contain a B* as a data member and/or as a method parameter).
Each CPP file (e.g. A.cpp) may include more than one header file (e.g. A.h and B.h). It's recommended that each CPP file should include its own header file first (e.g. A.cpp should include A.h and then B.h, whereas B.cpp should include B.h and then A.h).
Each header file should contain only the declaration, and not the definition of the class: for example it will list the signatures of the class' methods, but not the method bodies/implementations (the method bodies/implementations will be in the .cpp file, not in the header file). Because the header files don't contain implemention details, they therefore don't depend on (don't need to see) details of other classes; at most they need to know that, for example, B is the name of a class: which it can get from a forward declaratin, instead of by including a header file in another header file.
You can also use forward declarations to get around the issue.
Try putting #ifndef, #define and #endif around your .h files.
I have a program that uses enum types.
enum Type{a,b,};
class A
{
//use Type
};
class B
{
// also use that Type
};
2 class are located in 2 different files.
Should I put the type definition in a headfile or
in class definition for each class?
If the enum is going to be used in more than one .cpp file, you should put it in a header file that will be included by each. If there's a common header file, you should use that, otherwise you may as well create a new header file for this enum
You should always attempt to limit the scope of types in C++, so the enum should probably be declaread at class scope. The enum will typically belong slightly more naturally in one class than the other - lets say class A, so you put it in the declaration of A in the a.h header:
// a.h
class A {
public:
enum Type { a, b };
...
};
Now you need to include a.h in the header that declares B:
// b.h
#include "a.h"
class B {
public:
void f( A::Type t ); // use the Type enum
...
};
I can see the point of Neil: it is a pet peeve for many programmers to see stuff on the global scope. otoh, imho, introducing a class just for an enum is not a good style: It is supposed to be enum not a class. However, putting the same enum list in both classes (is what you were asking) would be the worst idea: we don't want to be repeating stuff.
Moreover, in most non-trivial codes, one might end up using more of such shared entities (more enums, const parameters, etc...) for implementation. So, I'd begin lumping all this into an implementation namespace (say "detail") which is a child namespace of your classes, and resides in a separate header file (say "detail.hpp"), included by all. For example:
// file A.hpp
#include "foo/detail.hpp"
namespace foo {
class A
{
// accessing enum as detail::a
};
}
// file B.hpp
#include "foo/detail.hpp"
namespace foo { class B { ... }; }
// file foo/detail.hpp
namespace foo { namespace detail {
enum { a,b, ... }
const int three = 3;
// etc...
// other implementation classes etc...
}}
And "detail" is nice and clean way of warning your class users to back off from whatever's declared in there. As your code gets bigger and these implementation details start growing in number you can break the dependencies into separate header files (detail1 detail2 etc...) and still keep one "detail" namespace (something which you can not do with a "class detail" for example).
The question is rather vague, but as a rule of thumb, you should try to minimize the redundancy in your code. Therefore, you should put the declaration of the enum to a header file.
It really depends on if the values are the same logical type, or if they just happen to have the same names. Would it make sense to assign an A::Type variable to a C::Type? If they are the same logical type, put them in a header that both include. To keep your build times low you probably want to put it in its own header file, but putting it in a shared header with other stuff works if you want to keep the number of files down.
Another option is to put the enum in a common base class that both inherit from (this may not make sense in this case, but it is another option).