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.
Related
I'm finishing up a C++ assignment and I'm running into an issue with connecting all the classes together. The classes have basic constructors, getters, setters, etc. so I'm confident the abundance of compiler errors I'm getting are due to me mix and matching all of my Classes incorrectly...
My classes are split up into cpp and h files and I've basically used the include statements every time that class needs something from another class. A basic diagram of which class needs what is shown below:
Basically what I'm trying to figure out is if having #include "Product.h" in both CustomerOrder and Retailer is messing things up or if I'm doing this all the wrong way.
Any help would be lovely!
Thanks!
EDIT:
Here's one instance of what each class is basically doing. The Customer class holds an array of CustomerOrders and CustomerOrders holds an array of Products etc. etc..
...
class Customer
{
private:
string customerName;
string customerID;
float balance;
static const int ORDERSIZE = 2;
CustomerOrder* orderList[ORDERSIZE];
Retailer retailer;
...
and Customer Order:
...
class CustomerOrder
{
private:
static const int SHOPSIZE = 20;
Product* shoppingList[SHOPSIZE];
...
First of all, your diagram is confusing. In OOP, arrows like the one you use indicate public inheritance, but that doesn't seem to be the case here (nor that it should).
Your question cannot be answered generally. You #include another class if you need the complete type. Otherwise, a forward declaration will do. That only has an impact on compilation speed. Nevertheless, the rule is to use forward declarations if you can and #includes if you must.
Here are some cases where you can get away with a forward declaration:
1.) Pointers:
class AnotherClass; // <-- forward declaration
class Example
{
// ...
AnotherClass *another_class;
};
2.) References:
class AnotherClass; // <-- forward declaration
class Example
{
// ...
void f(AnotherClass &another_class);
};
3.) Return values:
class AnotherClass; // <-- forward declaration
class Example
{
// ...
AnotherClass Get();
};
As soon as you are actually using the object of the forward-declared class, you need to have the #include. If you forget, the compiler will remind you.
Caveat 1: Pay attention when you use forward-declared (i.e. so-called "incomplete") types in standard containers. Your compiler may allow this, but it's undefined behaviour to do so!
class Example; // forward declaration
std::vector<Example> v; // undefined behaviour!
Caveat 2: Don't attempt to forward-declare standard classes. Just do #include <vector>, #include <string> and so on and let the compiler figure out how to optimize compile time.
Edit: Actually, the linker, rather than the compiler, will remind you if you forget to include a forward-declared class you cannot forward-declare, but that's just a nitpick :)
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?
Yeah the question topic has been discussed so many times. And I'm almost clear about the difference. I've just one doubt related to an example in the book.
This question is related to my previous question, where I presented 2 classes taken as example in the book C++ Primer.
In reference to those classes, the book quotes the following paragraph, specially related to the declaration of member function of WindowManager class as friend function. Here's what it says:
Making a member function a friend requires careful structuring of our programs to
accommodate interdependencies among the declarations and definitions. In this
example, we must order our program as follows:
First, define the Window_mgr class, which declares, but cannot define, clear.
Screen must be declared before clear can use the members of Screen.
Next, define class Screen, including a friend declaration for clear.
Finally, define clear, which can now refer to the members in Screen.
The code I presented in that question follows this structure only. But it seems that it is not working out. This makes me think if the above points are misguiding or I didn't implement it correctly.
The problem is, when I declare the clear function as friend function in ScreenCls class, I fall into cyclic inclusion of header files. I'll brief out the specific part of both classes here again:
ScreenCls.h:
#ifndef SCREENCLS_H
#define SCREENCLS_H
#include <iostream>
#include "WindowManager.h"
using namespace std;
class ScreenCls {
friend void WindowManager::clear(ScreenIndex);
// Some other code
}
Here I've to include the WindowManager.h header file, as clear function is now using the ScreenIndex defined there. Forward Declaration won't work here (Correct me if I'm wrong).
Now, next we move on to WindowManager.h:
#ifndef WINDOWMANAGER_H
#define WINDOWMANAGER_H
#include <iostream>
#include <vector>
#include "ScreenCls.h"
using namespace std;
class WindowManager {
public:
// location ID for each screen on window
using ScreenIndex = vector<ScreenCls>::size_type;
private:
vector<ScreenCls> screens{ ScreenCls(24, 80, ' ') };
};
And concentrate onto the declaration of screens here. They have used list initializer to add a default ScreenCls to the vector. So, here again we need to include the WindowManager.h. And now we are into cyclic inclusion. This prevents my project from building.
However, if I change the friend function declaration to make the entire class as friend, then I can work with forward declaring the WindowManager class. In that case, it will work fine.
So, basically friend function isn't working here, but friend class is working. So, is it that the above points are not going well with their implementation, or there's something wrong with my classes? I just want to know this to clearly understand the concept of header inclusion and forward declaration.
The questions linked in my previous question describe that well. But it's just that it's not working in the above situation, so I'm asking it again.
I guess your problem is with the screen initializer. You cannot initialize any data in *.h files that are inside a class. So, I suggest you to do something like that:
#ifndef WINDOWMANAGER_H
#define WINDOWMANAGER_H
#include <iostream>
#include <vector>
//#include "ScreenCls.h"
using namespace std;
class ScreenCls;
class WindowManager {
public:
// location ID for each screen on window
using ScreenIndex = vector<ScreenCls>::size_type;
private:
vector<ScreenCls> screens; //{ ScreenCls(24, 80, ' ') }; remove this
};
As long as you are not using the class, i.e. calling a method on an object or calling new for instance or reserving an Array of instances of the class you can go with forward declarations only. As a rule of tumb: if the compiler does not complain when you use forward declarations, use them and avoid includes which slow down compilation.
Only danger: when you cast with multiple inheritance and don't have the include, the cast will not work well - but this usually you would do in the .cpp where you should include classes you use.
Is there any reason why one shouldn't #include another file from within a class declaration when that class defines numerous private constants?
I'm writing a class which adheres to a simple state-transition system and defines a processing schedule consisting of several states, each of which consist of a series of steps. Because the class has to refer to these states and steps in various functions (for example, when determining which processing to apply based on the current state and step), I end up defining a bunch of private enum's within the class's declaration to make the implementation readable (so I can refer to things like kStates_ModeTransition and kStateSteps_ModeTransition_PrepareNewSetup etc, rather than just using the raw integer values associated with these states and steps).
As the list of states and state-steps has grown longer, this collection of enum's has become a fairly long, awkward chunk of code in the middle of the class declaration, and I feel these constants are more connected to the implementation than the interface - a user of the class doesn't necessarily have to know about them. Is there any reason why I shouldn't move all of these enum's to another file and then just #include that file into the private section of the class declaration? I haven't encountered another situation where it seemed appropriate to use a #include within the body of a class, so I'm wondering if there's a better way to handle this or any particular reason such an #include would be bad form. Furthermore, is there any sensible standard file extension to use on such a file, used only for text insertion (it isn't really a header...)? Just .txt?
Thanks!
Edit: A bit more to see if one of the mentioned alternatives completely dissolves my dilemma:
Trying to stick only to the essentials, here's an example of my current structure
// Processor.h
class Processor
{
public:
Processor();
void Process( float* input, float* output, int numSamples );
private:
// List of possible states
enum
{
kStates_Default,
kStates_SettingChangeImmediate,
kStates_SettingChangeCrossfade,
kStates_SpecialProcessing,
kStates_NumStates
};
// Lists of steps for each state...
enum
{
kStateSteps_Default_PrepareInput,
kStateSteps_Default_CalculateIntermediateValues,
kStateSteps_Default_CalculateOutput,
kStateSteps_Default_NumSteps
};
// Imagine more lists for other states here, with comments...
// Becoming quite long...
// Private functions used in implementing various processing steps
// (some are used by multiple state-steps in varying ways)
void PrivateFunction1();
void PrivateFunction2();
// Some member variables here
};
This is used in a real-time processing context in order to better balance DSP load when performing block-processing tasks. In reality, this class inherits from a base class which handles the actual scheduling of calls to Process, updating the current state and state-step as needed. Process() then consists of a switch statement which performs certain processing functions and IO based on the current state and state-step of the object.
The values declared in the enums are used within Process() and other private member functions inside processor.cpp, and nowhere else. I've declared them as private member variables to scope them to within the class. Is there a way to declare them inside the .cpp and achieve the same scoping? These are all meant to be constant integers optimized away at compile time and are essentially being used as #define 's - I just don't want to use macros.
All includes are just text inclusion. Since the file you're including contains C++ syntax, it should have a C++ header extension (.h or .hpp or etc.).
You may not need to include it into the declaration (I could speak to this more certainly if you post some code) ... you could just include it into the implementation files, and declare any enum member variables as int ... using typedefs (aliases for int) if you want to give them descriptive type names. Or if you're using C++11, you can forward declare your enum types without defining them, and then you enum member variables will be typesafe, preventing assignment of the wrong sort of enum value.
As for your question of whether there's a reason why you shouldn't move the enums out of your class declaration into another file and include that file: one can always invent reasons not to do things, such as "our Coding Standards say never to include a file other than at top level, at the top of the file", but if such arbitrary reasons don't apply to you then no, there's no reason. Do what makes the most sense in terms of code maintainability.
Using an #include in the middle of a class is highly irregular and could cause problems. It's much better if you declare your constants in either their own namespace or class.
For instance, this is a bad idea:
class Foo
{
#include "foostuff.h"
};
The more typical pattern is:
#include "foostuff.h"
class Foo
{
void bar(int x = FooStuff::const_x);
};
Inside foostuff.h you'd be careful to namespace things so they won't collide with other parts of your application.
The C++ way of doing things encourages the re-use of constants between different parts of your application instead of using #define to create macros that, once expanded, have no particular association.
All "include" files should be either .h for plain C or .hpp for anything that requires a C++ capable compiler to interpret. Anything else is non-standard and will, at the very least, lead to scorn from anyone who has to maintain your code.
New C++11 enum class may be forward declared and real definition moved to implementation. That will clean the mess and reduce annoyance.
// Procesor.hpp
class Processor
{
public:
Processor();
void Process( float* input, float* output, int numSamples );
private:
// Type of possible states
enum class kState;
kState somethingDealingWithState( kState s );
};
// Processor.cpp
// List of possible states
enum class Processor::kState
{
Default,
SettingChangeImmediate,
SettingChangeCrossfade,
SpecialProcessing,
NumStates
};
Processor::kState Processor::somethingDealingWithState( kState s )
{
if ( s == kState::Default )
{
return kState::SpecialProcessing;
}
return kState::Default;
}
In the end, it seems the best way to achieve equivalent functionality while gaining the benefit of separating the enumeration details into the .cpp implementation file is to use a forward declaration of a struct within the private portion of the class, and to then define that struct to contain the desired enum's from within the .cpp file.
// Processor.h
class Processor
{
public:
Processor();
void Process( float* input, float* output, int numSamples );
private:
struct States; // Used to scope State enum to within class
struct StateSteps; // Used to scope StateStep enums to within class
// Other stuff...
}
// Processor.cpp
struct Processor::States
{
enum
{
Default,
SettingChangeImmediate,
SettingChangeCrossfade,
SpecialProcessing,
NumStates
};
}
struct Processor::StateSteps
{
enum
{
Default_PrepareInput,
Default_CalculateIntermediateValues,
Default_CalculateOutput,
Default_NumSteps
};
enum
{
SettingChangeImmediate_FirstStep,
// ... other state-steps...
};
};
Here's why I think this structure is best in this particular use-case:
All enum listings are moved to the .cpp file, out of the middle of the header as desired, and additional StateStep enums which contain the same values (say, counting up from 0) may be added into the definition of the StateSteps struct without disturbing the .h header (while we could add entries to a forward-declared enum class, we couldn't have repeats of the same value and would need to add another enum class to the header).
All of the enums are scoped within the private portion of the class as before (albeit within another struct as well).
Enums which are being used to define compile-time integer constants may remain anonymous and not strongly typed enum class constructs, which may mislead others as to how the enums are being used (in the current use-case, we WANT to be able to compare different stateStep enum values to the same integer currentStep, depending on the current state, as we could with the originally defined anonymous enums).
Previous answers helped get me to this conclusion, but I feel that this is a way which most closely duplicates the functionality of the original definitions while moving them out of the .h file!
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.