Nested classes definition and initiation through files - c++

I'm trying to make class functions I can tack on to other classes, like with nested classes. I'm still fairly new to C++, so I may not actually be trying to use nested classes, but to the best of my knowledge that's where I'm at.
Now, I've just written this in Chrome, so it has no real use, but I wanted to keep the code short.
I'm compiling on Windows 7, using Visual Studio 2015.
I have two classes in file_1.h:
#pragma once
#include "file_2.h"
class magic_beans{
public:
magic_beans();
~magic_beans();
int getTotal();
private:
double total[2]; //they have magic fractions
}
class magic_box{
public:
magic_box(); //initiate
~magic_box(); //make sure all objects have been executed
void update();
magic_beans beans; //works fine
magic_apples apples; //does not work
private:
int true_rand; //because it's magic
};
... And I have one class in file_2.h:
#pragma once
#include "file_1.h"
class magic_apples{
public:
magic_apples();
~magic_apples();
int getTotal();
private:
double total[2];
}
Now, I've found that I can simply change:
magic_apples apples;
To:
class magic_apples *apples;
And in my constructor I add:
apples = new magic_apples;
And in my destructor, before you ask:
delete apples;
Why must I refer to a class defined in an external file using pointers, whereas one locally defined is fine?
Ideally I would like to be able to define magic_apples the same way I can define magic_beans. I'm not against using pointers but to keep my code fairly uniform I'm interested in finding an alternative definition method.
I have tried a few alternative defines of magic_apples within my magic_box class in file_1.h but I have been unable to get anything else to work.

You have a circular dependency, file_1.h depends on file_2.h which depends on file_1.h etc. No amount of header include guards or pragmas can solve that problem.
There are two ways of solving the problem, and one way is by using forward declarations and pointers. Pointers solve it because using a pointer you don't need a complete type.
The other way to solve it is to break the circular dependency. By looking at your structures that you show, it seems magic_apples doesn't need the magic_beans type, so you can break the circle by simply not includeing file_1.h. So file_2.h should look like
#pragma once
// Note no include file here!
class magic_apples{
public:
magic_apples();
~magic_apples();
int getTotal();
private:
double total[2];
}

Related

Minimizing the amount of header files needed using the Builder/Fluent pattern

I am experimenting with the Builder/Fluent style of creating objects trying to extend some ideas presented in a course. One element I immediately didn't like with my test implementation was the large number of additional header files the client needs to include for the process to work, particularly when I wish to make use of public/private headers via the pImpl idiom for purposes of providing a library interface. I'm not entirely certain whether the problem lies with my implementation or I'm just missing an obvious 'last step' to achieve what I want.
The general gist is as follows (using the toy example of Pilots):
Firstly the client code itself:
(Note: for brevity, various boilerplate and irrelevant code has been omitted)
Pilot p = Pilot::create()
.works().atAirline("Sun Air").withRank("Captain")
.lives().atAddress("123 Street").inCity("London")
What's happening here is:
In Pilot.h, the Pilot class is defined with a static member method called create() that returns an instance of a PilotBuilder class defined in PilotBuilder.h and forward declared in Pilot.h
Essentially the PilotBuilder class is a convenience builder only used to present builders of the two different facets of a Pilot (.works() and .lives()), letting you switch from one builder to another.
Pilot.h:
class PilotBuilder;
class Pilot {
private:
// Professional
string airline_name_, rank_;
// Personal
string street_address_, city_;
Pilot(){}
public:
Pilot(Pilot&& other) noexcept;
static PilotBuilder create();
friend class PilotBuilder;
friend class PilotProfessionalBuilder;
friend class PilotPersonalBuilder;
};
Pilot.cpp:
#include "PilotBuilder.h"
PilotBuilder Pilot::create() {
return PilotBuilder();
}
// Other definitions etc
PilotBuilder.h
#include "public/includes/path/Pilot.h"
class PilotProfessionalBuilder;
class PilotPersonalBuilder;
class PilotBuilder {
private:
Pilot p;
protected:
Pilot& pilot_;
explicit PilotBuilder(Pilot& pilot) : pilot_{pilot} {};
public:
PilotBuilder() : pilot_{p} {}
operator Pilot() {
return std::move(pilot_);
}
PilotProfessionalBuilder works();
PilotPersonalBuilder lives();
};
PilotBuilder.cpp
#include "PilotBuilder.h"
#include "PilotProfessionalBuilder.h"
#include "PilotPersonalBuilder.h"
PilotPersonalBuilder PilotBuilder::lives() {
return PilotPersonalBuilder{pilot_};
}
PilotProfessionalBuilder PilotBuilder::works() {
return PilotProfessionalBuilder{pilot_};
}
As you can imagine the PilotProfessionalBuilder class and the PilotPersonalBuilder class simply implement the methods relevant to that particular facet eg(.atAirline()) in the fluent style using the reference provided by the PilotBuilder class, and their implementation isn't relevant to my query.
Avoiding the slightly contentious issue of providing references to private members, my dilemma is that to make use of my pattern as it stands, the client has to look like this:
#include "public/includes/path/Pilot.h"
#include "private/includes/path/PilotBuilder.h"
#include "private/includes/path/PilotProfessionalBuilder.h"
#include "private/includes/path/PilotPersonalBuilder.h"
int main() {
Pilot p = Pilot::create()
.works().atAirline("Sun Air").withRank("Captain")
.lives().atAddress("123 Street").inCity("London");
}
What I cannot figure out is:
How do I reorder or reimplement the code so that I can simply use #include "public/includes/path/Pilot.h" in the client, imagining say, that I'm linking against a Pilots library where the rest of the implementation resides and still keep the same behaviour?
Provided someone can enlighten me on point 1., is there any way it would be then possible to move the private members of Pilot into a unique_ptr<Impl> pImpl and still keep hold of the static create() method? - because the following is obviously not allowed:
:
PilotBuilder Pilot::create() {
pImpl = make_unique(Impl); /* struct containing private members */
return PilotBuilder();
}
Finally, I am by no means an expert at any of this so if any of my terminology is incorrect or coding practices really need fixing I will gladly receive any advice people have to give. Thank you!

Using an object outside of its declaration file (C++)

(it is be possible that this question has been asked very often already and i am sorry about this repost, but anything i found just didnt help me, since i am relatively a beginner at c++)
so here is an example to show my problem
i have the class monster
class Monster{
public:
Monster();
void attack();
private:
int _health;
int _damage;
};
and i have the class Level
class Level{
Level();
};
i have created the object "snake" from the class Monster in my "main.cpp"
#include "Monster.h"
int main(){
Monster snake;
}
now what do i do if i want to use "snake" in my "Level" class? if i want to do "snake.attack();" inside of "Level.cpp" for example?
If i declare it again in "Level.cpp" it will be a seperate object with its own attributes wont it?
i have always been making the member functions of my classes static until now, so i could do "Monster::attack();" anywhere in my program but with this tachnique i cant have multiple objects doing different things depending on their attributes (snake1, snake2, bat1, etc...)
thanks for the help in advance!
(and sorry for the possibly reoccuring question)
Presuming those snips are your .h files.
Your level.cpp should something like this:
#include "level.h" // its own header
#include "monster.h" // header with Monster::attack() declaration
Level::DoAttack(Monster& monster) { // using snake as parameter.
health = health - monster.attack(); // monster hits us, subtract health.
}
monster.h would be
class Monster{
public:
Monster();
void attack();
private:
int _health;
int _damage;
};
and monster.cpp
Monster::attack() {
// code to calculate the attack
}
I could not completely understand your questions.But from what I understood.I think you want to access a Monster object instantiated in main() to be used inside level.So,here is what you can do.Add a constructor inside the level class which takes a monster object as an argument.Then instantiate a level object and pass the monster object in it.Like this,
Level l=new Level(snake);
By declaring a class you're not creating any objects. You normally declare a class by including the corresponding header file.
So, in Level.h you'd #include <Monster.h>, then you can reference it inside Level.
But seriously, you can't write much C++ code without understanding the basic things such as declaration vs. definition, header files (.h), classes vs. objects, pointers and references, etc. It would be best to invest in a book or at least to read some tutorials online.

c++ class circular reference?

I am working on a little game engine but I got stuck at something. Explanation : I have two classes, cEntity And ObjectFactory :
cEntity
class cEntity:public cEntityProperty
{
Vector2 position;
Vector2 scale;
public:
cEntity(void);
cEntity(const cEntity&);
~cEntity(void);
public:
void init();
void render();
void update();
void release();
};
ObjectFactory
#include "cEntity.h"
#include <vector>
class ObjectFactory
{
static std::vector<cEntity> *entityList;
static int i, j;
public:
static void addEntity(cEntity entity) {
entityList->push_back(entity);
}
private:
ObjectFactory(void);
~ObjectFactory(void);
};
std::vector<cEntity> *ObjectFactory::entityList = new std::vector<cEntity>();
Now I am adding new cEnity to ObjectFactory in cEntity constructor but facing an error related to circular references: for using ObjectFactor::addEntity() I need to define the ObjectFactory.h in cEntity class but it creates a circular reference.
I think your code might have an underlying architectural issue given how you have described the problem.
Your ObjectFactory should be handling the cEntities, which in turn should be unaware of the "level above". From the description of the problem you are having, it implies that you're not sure what class is in charge of what job.
Your cEntitys should expose an interface (i.e. all the stuff marked "public" in a class) that other bits of code interact with. Your ObjectFactory (which is a bit badly named if doing this job, but whatever) should in turn use that interface. The cEntitys shouldn't care who is using the interface: they have one job to do, and they do it. The ObjectFactory should have one job to do that requires it to keep a list of cEntitys around. You don't edit std::string when you use it elsewhere: why is your class any different?
That being said, there's two parts to resolving circular dependencies (beyond "Don't create code that has circular dependencies in the first place" - see the first part to this answer. That's the best way to avoid this sort of problem in my opinion)
1) Include guards. Do something like this to each header (.h) file:
#ifndef CENTITY_H
#define CENTITY_H
class cEntity:public cEntityProperty
{
Vector2 position;
Vector2 scale;
public:
cEntity(void);
cEntity(const cEntity&);
~cEntity(void);
public:
void init();
void render();
void update();
void release();
};
#endif
What this does:
The first time your file is included, CENTITY_H is not defined. The ifndef macro is thus true, and moves to the next line (defining CENTITY_H), before it moves onto the rest of your header.
The second time (and all future times), CENTITY_H is defined, so the ifndef macro skips straight to the endif, skipping your header. Subsequently, your header code only ever ends up in your compiled program once. If you want more details, try looking up how the Linker process.
2) Forward-declaration of your classes.
If ClassA needs a member of type ClassB, and ClassB needs a member of type ClassA you have a problem: neither class knows how much memory it needs to be allocated because it's dependant on another class containing itself.
The solution is that you have a pointer to the other class. Pointers are a fixed and known size by the compiler, so we don't have a problem. We do, however, need to tell the compiler to not worry too much if it runs into a symbol (class name) that we haven't previously defined yet, so we just add class Whatever; before we start using it.
In your case, change cEntity instances to pointers, and forward-declare the class at the start. You are now able to freely use ObjectFactory in cEntity.
#include "cEntity.h"
#include <vector>
class cEntity; // Compiler knows that we'll totally define this later, if we haven't already
class ObjectFactory
{
static std::vector<cEntity*> *entityList; // vector of pointers
static int i, j;
public:
static void addEntity(cEntity* entity) {
entityList->push_back(entity);
}
// Equally valid would be:
// static void addEntity(cEntity entity) {
// entityList->push_back(&entity);}
// (in both cases, you're pushing an address onto the vector.)
// Function arguments don't matter when the class is trying to work out how big it is in memory
private:
ObjectFactory(void);
~ObjectFactory(void);
};
std::vector<cEntity*> *ObjectFactory::entityList = new std::vector<cEntity*>();

Can't use a class that is defined in another hpp file

I'm having a little problem trying to use my "gameAux" class in "userAux.hpp" file I made.
Here are the two hpp files I made.
I marked the place where I get an error.
userAux.hpp:
#include "gameAux.hpp"
class userAux{
int gameId;
int userId;
int rate;
gameAux aGame; <---error: ‘gameAux’ does not name a type
};
gameAux.hpp:
#include "userAux.hpp"
class gameAux{
int gameId;
userAux aUser; <--- OK
};
I'll be very happy if someone could point out what's the problem :)
You cannot have one class include an instance of another class, and have that other class include an instance of the first class. That's an infinite recursion and obviously cannot work.
The answer is to use pointers and forward declarations.
class gameAux; // forward declaration
class userAux{
int gameId;
int userId;
int rate;
gameAux* aGame;
};
class gameAux{
int gameId;
userAux* aUser;
};
When two classes depend on each other like this I would be tempted to place them both in the same header file. However if you want separate header files then you could forward declare each class in the other classes header file. That way neither header file needs to include the other.
Your problem is that both of your classes depend on each other. When the compiler goes to see how much space it needs to reserve for gameAux objects, it says 'ok, I need an int and a userAux to fit in there'. So the next question is, how much space does it need for ints and userAux objects?
Then when it tries to figure out how much space it needs for a userAux object, it says 'ok, three ints and a gameAux object'... and there's the problem. It's going to keep going back and forth between those two files, trying to figure out how much space it needs for each thing, and never be able to figure it out.
To solve this, you need to make one of your classes depend on a reference or pointer to the other class. Since references and pointers always take up the same amount of space on a given system, the compiler will be able to allocate space for a userAux if it sees this:
class gameAux;
class userAux{
int gameId;
int userId;
int rate;
gameAux &aGame; // or gameAux *aGame; // <---error: ‘gameAux’ does not name a type
};
and then it will have a fine time allocating space for both of the objects, no problems ^^
EDIT: Also, you won't need to #include the header file for gameAux any more at the top of userAux.hpp - just forward-declare gameAux like so at the top of the file: class gameAux.
You don't need to include the entire class definition. You can avoid a circular dependency by just forward declaring, and using a pointer:
#include "gameAux.hpp"
class gameAux; // forward declaration
class userAux{
int gameId;
int userId;
int rate;
gameAux *aGame;
};
and vice versa in the other file. Then #include the appropriate hpp header in the implementation source file for each class.

Class naming and namespaces

Will using same class name within multiple namespaces get me into trouble? I also try to remove dependency to math library. What do you think about following design.
first file
#define MATH_RECTANGLE_EXISTS
namespace math {
class Rectangle : Object2D {
public:
float perimeter();
float area();
float x,y,w,h;
};
}
other file
#define GRAPHIC_RECTANGLE_EXISTS
#ifndef MATH_RECTANGLE_EXISTS
//is this a good idea to remove dependency?
namespace math {
class Rectangle {
public:
float x,y,w,h;
}
}
#endif
namespace graphics {
class Rectangle : math::Rectangle {
public:
void Draw(Canvas &canvas);
void Translate(float x, float y);
};
}
EDIT
What about this approach to remove dependency?
** 1st file**
namespace common {
class Rectangle {
float x,y,w,h;
};
}
math lib file
#define MATH_RECTANGLE_EXISTS
namespace math {
class Rectangle : public common::Rectangle, public Object2D {
public:
float perimeter();
float area();
};
}
graphic file
#define GRAPHIC_RECTANGLE_EXISTS
namespace graphics {
#ifndef MATH_RECTANGLE_EXISTS
class Rectangle : public math::Rectangle {
#else
class Rectangle : public common::Rectangle {
#endif
public:
void Draw(Canvas &canvas);
void Translate(float x, float y);
};
}
Thanks in advance.
I don't see the problem with reusing the same identifier within different namespaces, that was they were created for after all.
However I would strongly urge you NOT to 'simulate' the inclusion of math::Rectangle. If you need the file then include it, but what you are doing is called copy/paste programming, and it leads to a good number of problems, essentially because your two pieces of code are not synchronized so any bug fix / feature addition to one is not reported on the other.
EDIT: answer to the Edit ;)
It is not clear from the comments so I will state it:
If you need the dependency (because you really USE the functionality offered), then you HAVE to include the header. On the other hand, if you only use inheritance to get something that have 4 corners and nearly no method, then you're better up rolling a new Rectangle class with the minimum functionality.
I can think of an edge case though. I am under the impression that you are not so much interested in the functionality but in fact interested in the possibility of reusing the methods in the Math library that have been tailored to take a math::Rectangle as a parameter.
According to Herb Sutter (in C++ Coding Standards I think), the free functions that are bundled with a class are part of the class public interface. So if you want those classes, you actually need the inheritance.
Now I can understand that you may have some reluctance in including a library that may be huge (I don't know your Math library). In this case you could consider splitting the Math library in two:
A MathShapes library, comprising the basic shapes and the methods that act upon them
A Math library, which includes MathShapes and add all the other stuff
This way you would only depend on the MathShapes library.
On the other hand, if you absolutely do not want the dependency, then a blunt copy/paste will do, but your solution of testing the presence of Math::Rectangle by testing the presence of its header guard is ill-fitted:
It only works if you get the header guard correctly
AND if the include is actually performed BEFORE the include of Graphics::Rectangle
Note that in the case in which Graphics::Rectangle is included before Math::Rectangle you may have some compilation issues...
So make up your mind on whether or not you want the dependency.
That is rather what namespaces are for, and a rectangle is both a mathematical and a graphical object.
The attempt to avoid including a header file however is very ill-advised. It achieves nothing other than a maintenance headache. A change in math::Rectangle should cause a rebuild of graphics::Rectangle - if they end up in a mismatch and you hide that from the compiler, you'll end up with a harder to debug run-time error.