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?
Related
I have been going through the code of a project and have encountered the statement
class foo;
.
.
.
.
foo* f1;
in various places. The class has not been declared in any of the headers included either. Can anybody tell me what that means.
It is a forward declaration. It can be used for classes, structs and functions, and it tells compiler that this is defined elsewhere or later.
For classes, there are (at least) two use cases.
1. Full definition not needed
After forward declaration, compiler does not know size or members of class, only name. That is enough for pointers to the class (and references which are basically syntactic sugar around pointers). But often pointer is enough, and then you can avoid including entire header file in another. This helps compilation speed, by avoiding need to recompile everything when one header changes.
myfuncs.h
class MyClass; // forward declaration
void helpMyClass(MyClass &needy);
// here this would give compiler error about incomplete type:
//void badHelp(MyClass needy); // value needs definition
myfuncs.cpp:
#include "myclass.h" // entire MyClass definition
void helpMyClass(MyClass &needy) {
needy.helpMe(false); // needs full definition
}
Important use case for this is the so called PIMPL idiom, also well covered here at SO under pimpl-idiom tag.
2. Two classes need to refer to each others
class node; // forward declarion
class collection {
node *frist; // pointer enabled by forward declaration
}
class node {
collection *owner; // already defined above so works too
}
In this case forward declaration is required to make this work nicely. Just saying in case you see it in the wild, there's the ugly way of using void pointer and casts, sometimes used when novice programmer does not know how this should be done.
I think you're referring to a forward declaration. It tells the compiler that a class named foo will be defined later. Until then it is an "incomplete type", meaning that pointers and references to the class can be defined. Instances of the class cannot be created until it is fully defined.
Your declaration is incorrect? I'm not sure.. I do know that you can't have "any" space "name".. Perhaps you missed an underscore?
I believe you meant:
class foo any_name();
In that case, it's forward declaring a function called any_name that returns a class instance of foo.
Example:
#include <iostream>
class foo any_name(); //The forward declaration..
class foo //the foo class implementation.
{
public:
foo(){std::cout<<"hey";}
};
class foo any_name() //The implementation of the function..
{
std::cout<<"any_name";
//return {}; //Can be used to return a constructed instance of foo.
};
int main()
{
any_name();
}
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.
When I use the pimpl idiom, is it a good idea to put all the methods definitions inside the class definition? For example:
// in A.h
class A {
class impl;
boost::scoped_ptr<impl> pimpl;
public:
A();
int foo();
}
// in A.cpp
class A::impl {
// method defined in class
int foo() {
return 42;
}
// as opposed to only declaring the method, and defining elsewhere:
float bar();
};
A::A() : pimpl(new impl) { }
int A::foo() {
return pimpl->foo();
}
As far as I know, the only problems with putting a method definition inside a class definition is that
(1) the implementation is visible in files that include the class definition, and
(2) the compiler may make the method inline.
These are not problems in this case since the class is defined in a private file, and inlining has no effect since the methods are called in only one place.
The advantage of putting the definition inside the class is that you don't have to repeat the method signature.
So, is this OK? Are there any other issues to be aware of?
I think you answered your own question : both solutions are equivalent.
However, I wouldn't be so sure that 'inlining has no effect since the methods are called in only one place' : an additional call could exists when the functions are not inlined. But chances are that the compiler is smart enough to optimize them away from the one-line forwarding calls in the outer class.
In the end, I believe it's just a matter of taste.
Advantages:
all code of the class is localized
Disadvantages:
for larger classes: when scrolling is needed, it becomes more difficult to know to which class the function belongs.
dependencies are more easily solved when functions reside after all class declarations. Otherwise, it might be needed that some class declarations are moved after others and some functions still have to be moved after the class declaration when there are mutual dependency of internal classes.
Usually I don't add methods to the Impl inner class, but I can't see any issue if you define the methods inline. It seems to me much more readable than having seperate declaration and definition.
Whether the compiler inlines the methods depends on the compiler and the passed parameters.
In the case of the pimpl idiom, I don't think it matters whether the methods are defined within the Imp's body or not. I personally like them defined outside, because it is easy to see what is really important (like member variables and list of methods).
It is possible to declare a class without defining it (forward declaration) as long as it is defined later on within the translation unit. In the case of functions, one can declare a function without defining it within the translation unit, and the linker will link it to its definition in a different translation unit. Is it possible to do the same with class declarations?
(if this is not possible, is there any use to a forwardly declared class without a definition in the current TL, or is that always an error?)
something like this, except this doesn't compile:
mymain.cpp:
class myclass; // declare without defining
myclass::myclass();
void myclass::barf();
int main() {
myclass *m = new myclass();
m->barf();
return 0;
}
myclass.cpp:
#include <iostream>
class myclass { // define the implementation
public:
myclass();
void barf();
};
myclass::myclass() { } //empty constructor
void myclass::barf() {
std::cout << "barfing\n";
}
It is possible to forward-declare a class, but only pointers and references to forward-declared classes can be used. You can't use an actual object of a forward-declared class because the compiler doesn't know enough about it; in particular it doesn't know how large the object is or what its members are. Trying to forward-declare member functions (as you have done) won't work because the syntax of the forward declaration doesn't allow you to specify whether the functions are virtual or non-virtual (or perhaps inherited from some base class).
It is not often useful to forward-declare a class in a source file, but it can be useful in a header file. In particular it's common to forward-declare a class in a library's public header file and use pointers to that type as opaque handles. The class definition remains private to the library but user code can pass around pointers to objects of that class without ever knowing what the class's implementation looks like. This works particularly well when the pointers are smart pointers.
You can, but only if you use exclusively pointers or references to that class. But you can't use code referring to that class' members (variables or methods). You can only use it to declare pointer variables to that class.
I would suggest you create a myclass.h header file with myclass' full declaration, and include that header in mymain.cpp.
You can only do that through hacks.
The declare before use rule doesn't hold within a class (see here).
Otherwise you can do that by declaring your function as a template function, whose template parameter is of myclass (in your example).
The only non-hack way is to define the class (ie. by including the header file its defined in).
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.