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.
Related
I have a project which includes 2 files: main.cc and header1.h. While main.cc instantiates a class "className" and calls the member functions of it, the header file includes definition of the class.
main.cc:
#include <header1.h>
int main(){
className classobject();
classobject.function1();
...
}
}
header1.h:
class className{
public:
className();
void function1();
...
};
double className::function1(){
double function2(){
...
}
}
With this, I met an error which says:"a function definition should not be placed before '{' token.
So I decided to put the definition of function2 outside of the class, and put it in a standalone .h file. In that way, my project would include 3 files, namely: main.cc, head1.h and function2.h file:
main.cc:
#include <head1.h>
int main(){
className classobject;
void classobject.function1();
...
}
head1.h:
#include <function2.h>
class className{
double function2();
...
}
function2.h:
double function2(){
...
}
Although function2 can also be defined as the class member function so that it can be moved out of function1 while inside the class, I want to know whether the above mentioned treatment is leagal. Besides, does the creation of header files have some implicit rules established by usage (common treatment)?
Could anyone give some comments? Thanks in advance.
The first problem in your code that I see is that you define className::function1 in a header, but forgot to declare it inline. The outcome is that you can only use the header in a single compilation unit †. That's a bad design. I recommend defining it in a source file instead.
Secondly, you try to define function2 inside another function. That's not allowed and therefore you got a compilation error. You say that you decided to move it's definition outside the class, but it's definition was already outside the class definition. Moving the definition outside the definition of className::function1 is indeed a correct choice.
If function2 is reusable outside it's use in className::function1, then it's indeed a good idea and perfectly legal to declare it in a separate header. But just like className::function1, you're defining function2 also in the header again and again without declaring it inline and therefore you will get in trouble if you try to use it in multiple compilation units. I recommend defining function2 in a source file as well.
† If you include the header in multiple compilation units, then each of those compilation units will contain the definition of the function. The One Definition Rule does not allow defining a function in more than one compilation unit. Functions that are marked inline are treated differently. They may be defined in multiple compilation units as long as they have an identical definition in each.
Do something like this in your className.hpp
class className{
public:
className();
private:
void function1();
};
Then in your className.cpp
#include"className.hpp"
className::className(){ /*defintion*/ }
void className::function1(){ /*definition*/ }
Then you could use a makefile in oder to compute the className.o file and link it to the main file.
If you want to define another function (like function2()), you can then define it the className.cpp
I am working on a codebase that is not my own, that has the following layout:
object.h:
// Objects are defined
// #include "tickets.h" (functions to access the objects)
// An access-handler object is defined
I want to introduce a class that knows about the objects, can be accessed from functions in tickets.h, but can also use the access-handler object. The functions are separate, i.e. class functions that are called in tickets.h do not use the access-handler (I wouldn't know where to start if that weren't the case).
Therefore my class needs to be defined before tickets.h, but some of its functions need to be defined after the access-handler. Is there a way to do this without splitting it up into two header files something like the following:
// Objects are defined
// -- include declaration of class, and definition of functions that tickets.h needs
// #include "tickets.h"
// An access-handler object is defined
// -- include functions of class that need the access-handler
This seems very messy splitting things up like this into two separate files, I was hoping to keep everything contained.
Thanks for any help, I clearly only have a very rudimentary understanding of declarations/definitions in c++.
EDIT: If I use forward declaration and include it before tickets.h (with the class declared in mynewclass.h and functions defined in mynewclass.cc) will mynewclass.cc be able to use objects declared after the inclusion of mynewclass.h? Namely the access-handler object.
EDIT2: Something like this:
object.h:
class obj { // definition }
#include "tickets.h"
class obj_handler {
public void handle { // code }
}
tickets.h:
void do_something(obj o){
communicator.foo();
}
My object (communicator):
class communicator {
public:
void foo() { // code }
void bar() { // use handle() from obj_handler }
}
As you can see, my communicator needs to be used in tickets.h, but can't be defined until after obj_handler. So where should I include it?
If I correctly understand your question - you can use forward declaration to solve this problem. This will allow you to declare some class before defining it's methods. For example:
// this is forward declaration of class A, no definition provided
class A;
class B
{
// uses A
A * a_;
};
// class A definition
class A
{
// may use class B now
B * b_;
};
I'm not quite sure whether I understand this right and don't have enough reputation here yet to make this a comment, so let me try to answer your question this way, please feel free to follow up if I'm guessing wrong:
I believe what you are referring to is an entire class definition, i.e., one including all function definitions within the class declaration. Other than that, it is not very common to see object definitions followed by preprocessor directives. What is typical though is a forward declaration of functions and a class prototype.
So, for example, you could declare in some header.h:
class C
{
public:
void method1(void);
int method2(void);
};
And in some implementation.cpp the definition of the functions like:
void C::method1(void) { /*...*/ }
In the other file preceded in the inclusion chain by your access-handler you then define the other function:
int C::method2(void) { /*...*/ }
What do you mean by access-handler, by the way?
Oh, and your linker likely will yell somewhat at you if you do function definition in a header file.
With regard to your addenda: everywhere you put a forward declaration, loosely speaking, the compiler will insert a copy of the declaration in question, consider it a soft link in the context of file systems. There are negative implications associated with it, like increased duration and the memory load of compilation if you have many forward declarations of the function signature or class. It's impossible to tell whether this will word in your particular situation since only you know the actual code in question. But most likely it would work.
Take a look at these pages:
http://en.wikipedia.org/wiki/Forward_declaration
When can I use a forward declaration?
I'm just beginning with C++, so I'm looking some code to learn. I found this code fragment in a Breakout game.
#pragma once
#include "force.hpp"
#include "brick.hpp"
#include <vector>
class Painter;
class Ball;
class Wall
{
public:
enum { ROWS_COUNT = 16,
COLS_COUNT = 8 * 3 };
enum { WIDTH = ROWS_COUNT * Brick::WIDTH,
HEIGHT = COLS_COUNT * Brick::HEIGHT };
Wall();
void draw(Painter &) const;
Force tick(const Ball &);
public:
typedef std::vector<Brick> Bricks;
Bricks bricks_;
};
The only part that I don't understand is the following:
class Painter;
class Ball;
What's mean that two "class [name];"? In the source code there are differents Painter.cpp, Painter.hpp, Ball,hpp, Ball.cpp.
This mean some kind of include?
Those are forward declarations, which can be used to say that a name exists, but no definition of it exists at this time yet, but I want to use the name.
Note that in the class, it only uses pointers and references to Painter and Ball. When using forward declarations, this is completely fine, but if you put in code that depends on knowledge about the internals of the Painter or Ball classes (like calling a function or using a member variable of the class), then you'd have to include the actual class declarations.
For example, notice how the header #includes the brick.hpp header, because the class has an std::vector<Brick> container, that stores copies of Brick objects, and needs to know sizeof(Brick). The header also uses Brick::WIDTH and Brick::HEIGHT.
Another common use case for forward declarations is to fix the circular dependency problem.
That is called a forward declaration.
That just means "Expect there to be a Ball class and Painter class sometime in the future."
What you're looking at is something called forward declaration of types.
The short explanation is that this kind of thing speeds up compilation, because the compiler does not have to look at the header files where these types are declared, you just tell it that the types exist. This is possible as long as you don't need to know exactly the type or use any members. This is a good practice in header files.
This in only something you do in the header files. In .cpp files you need to include the headers where the types are declared, because here you'll most probably use the types and thus must know the real type and what it looks like.
I was wondering if there is a way to put objects of a class in a header?
For example:
class MyClass {
} object;
If I made an object there and then include the header in more than one source file, I get an error of multiply defined symbols found. I am new so don't understand fully everything.
Also, I want to do something like object.function() inside of a different function which is a member of a different class how can I do that?
Assuming you want a single object, in the header file just declare the object:
extern blabla object;
and then in one source file define it:
blabla object;
As for calling a method on an object from a different class, that is perfectly fine as long as the method is public.
class foo
{
public:
void public_method();
private:
void private_method();
};
void some_other_class::method(foo &f)
{
f.public_method(); // this is fine
f.private_method(); // this is not okay, private_method can only be called from
// within foo
}
There's also a third visibility (protected), which comes into play once you start dealing with inheritance.
You can find ways to do it (see the other answers), but just don't do it. As you said, you are new to C++, so better learn the good practices, and when you need global objects - create them in the source (cpp) file.
Besides it, try to avoid using global objects at all, and define your objects inside the classes or functions.
It's not a good practice to put definitions in header files as this would result to the error you encountered. Although there are ways to get around this (extern, header guard), it should be avoided as much as possible. Just remember, put declarations in header files, definitions in source files.
About your second question note you can also call a static method using the :: operator and the class name (without an instance) :
void AnOtherClass::method()
{
TheFirstClass::static_method();
}
You could also make a use of the singleton pattern, if that fits your need in this case.
For your second question. You can always make a class object as a (private) member variable of the class you want to call object.function() from.
For example:
// File a.h, includeguards etc. left out for clarity
class A {
public:
void func();
};
// File b.h
#include "a.h"
class B {
public:
void func();
private:
A object;
};
// File b.c
#include "b.h"
void B::func()
{
object.func();
}
Hope that helps.
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).