I have few files:
main.cpp:
int main{
...
while(1){
...
draw();
...
}
...
return 0;
}
and draw.cpp:
I want to see objects and all manipulations here.
I cant make objects local to draw(), because draw() is inside loop,
so I will get many object constructor/destructor calls - so they are global. Also
I ve made init block to prevent unnecessary calls/assignments
draw.cpp:
Object A, B;
int initialized = 0;
void draw(){
if(!initialized){
A.initialization;
B.initialization;
initialized = 1;
}
A.move(1,1);
B.rotate(45);
}
It works, but Im looking for better way to organize my code
Added:
Thanks for answers, looks like I have to read something about pattern designs
Here's steps to make it work better:
Add a struct containing all your objects near main().
pass it to draw(MyStruct &s); via reference parameter.
you're done.
Option 1
Define a new Class called Draw and put the attributes into it. You need to modify main and draw files for this. With this you can avoid declaring anything global
Option 2
Define a class within draw.cpp called draw and add your current global variables as static member variables. Initialize and use them using static functions. With this you dont have to change main.
This design technique is called Singleton (one of the design patterns)
Example code
draw.cpp
class Draw
{
public:
object A, B;
static void init()
{
// init A
// init B
isInitialized = 1;
}
static int isInitialized;
static Object & getA()
{
if(isInitialized == 0)
{
init();
}
return A;
}
// similarly B
};
Related
I have many function definitions which I have placed in different cpp files with function declarations in their respective .h files.
I have a set of a variables which I have placed in a .h file. These variables need to modified by different functions. I am using static to keep the changes from each function, but I heard it is a bad coding practice. How else to do it ? For eg -
variables.h
class variable{
static int x;
static int y;
};
function1.h
class function(){
public:
void function1();
}
similar for function 2
function 1.cpp
void function1(){
// does something with x and y (used as (variable::x=2;variable::y=3)
}
function2.cpp
void function2(){
// does something with x and y (used as variable::x+=2;variable::y+=2)
}
main.cpp
int variable::x;
int variable::y;
int main(){
obj.function1(); (obj is object of function1 class)
obj2.function2(); (obj2 is object of function2 class)
cout << variable::x << variable::y << endl;
}
I was was using different objects in different cpp files but changes in one function were not reflecting in other. How it use it please help?
You can simply move these variables into another class:
struct Shared {
int x;
int y;
};
Now you can pass an instance to this class as parameter to your function, this is called dependency injection:
void foo(Shared& shared) {
shared.x = 4;
shared.y = 2;
}
This is better because you don't have any global state anymore. You could use the function multiple times independent from each other by referencing a different instance of the Shared class.
It is very common to take this a step further by "injecting" the instance in the constructor of that class. This is helpful if the instance of that class should always reference the same instance:
struct Foo {
Shared& m_shared;
Foo(Shared& shared)
: m_shared(shared)
{
}
void foo() {
m_shared.x = 4;
m_shared.y = 2;
}
};
Yes, as you mentioned using static variable for this purpose is kind of anti-pattern. A better pattern (without knowing the background of the application) is using a composition pattern. If your functions f1() and f2() are in classes C1 and C2, you would e. g. create an additional data object D1 (with the variables in question), and inject and object of D1 in the constructor of C1 and C2, so both classes operation on a data object. There are also other solutions to this situation, but I guess thats the most general. Google for C++ Design Pattern to find more general patterns.
You can use smart pointers for global objects
struct MyGlobal
{
std::shared_ptr<Core> core;
MyGlobal(){ core=std::make_shared<Core>(); }
void changeVariableX(int X)
{
core->X = X;
}
};
You can move, copy, do whatever you want with MyGlobal instances and they still point to same core item. Just make sure all of them are populated from same instance like this:
int main()
{
MyGlobal global;
auto something = useSomeFunctionWith(global);
auto somethingElse = useAnotherFunctionWith(global);
...
// use something and somethingElse to change X, both point to the same X
}
If functions will not be thread-safe then you should add a lock-guard into changeVariableX method.
I'm developing a little game engine for Android with Android NDK and opengl es 2.0, recently the project is getting big, and I need to refactor some code, and I couldn't find a proper design pattern for the next problem.
On android when the app reach the OnPause() state the opengl context is destroyed, but the state of the variables and objects in java and c++ are maintained. so each time the player pauses and resumes the app I have to reinitializate the opengl part, buffers, shaders, vertex, etc.
I have classes like "Square" that makes "square objects", and each one has its own attributes, and each "square object" can be drawn, so the squares can access to static (opengl) members of the class, that are used to be properly rendered. So this static members must be initialized before objects can be drawn, I do it when the opengl context is created or recreated.
moreover each class has its own opengl attributes, so each class is initialized individually with its own parameters, so I want a design in what each class can set some initial parameters, pass or catch those parameters to initialize the static members of the class (I forgot to say that these parameters are private). But as I said before, these parameters need to be reinitialized each time the app is resumed.
currently I initialize these members individually like
Square::init(/*hardcoded parameters*/);
Circle::init(/*hardcoded parameters*/);
Triangle::init(/*hardcoded parameters*/);
Polygon::init(/*hardcoded parameters*/);
Shape::init(/*hardcoded parameters*/);
.
.
.
.
// Many other inits.....
.
and I want to write something like
// here all the classes with opengl part are initialized
// all init methods of each class are called here, with their respective parameters
Opengl_Initializer::init(); // <--- magic way, no other init calls
So I want to set some (static/harcoded) variables to the class and then when the opengl context be created, the class be initialized in a "magic" way, and not having the need to code the call to an init method for each class.
I've tried to use inheritance, but the issue is that I need to initialize the class not the object, also tried to implement a static object and initialize this object in the cpp file, and store a pointer to the object in a vector when this is created in his contructor, in a vector that is in the object's own class, but this design has gave me many problems.
Does anyone know some design that can help me?
EDIT: the stucture of my classes
the init() function is really big because shader and frag parameters are paths file and I perform some task on them, pass the result of that perform to opengl and returns me a ID that is the program static variable, all clases with opengl part implement this same process, the parameter camera is just to attach it into a camera
class Square {
// static variable all classes have
static GLuint program;
// other glparameters not in common, initialized in the same static init() method
static GLint uniform1;
static GLint uniform2;
public;
// the static init function has the same header on all the classes
static init(const char* shader, const char* frag, const char *camera);
}
and maybe some structure I'd want is
class Square {
static GLuint program;
static const char *vertex = "hardcode";
static const char *frag = "hardcode";
static const char *cam = "harcode";
static init();
/// or somethig like
static Initializer init(
"harcode shader", "hardcode frag", "hardcode camera",
[&] (void) ->void {
//this is the init function
}
);
public:
}
This is one more solution how your task can be solved. The idea is to have some initialization list (std::vector) of functions that should be called in yout Opengl_Initializer::init() :
std::vector<std::function<void()>> initializer_list;
If we can put all your Square/Circle/Triangle... init functions into this list, your task become trivial - just iterate list and call all functions:
// inside Opengl_Initializer::init()
for (auto fn : initializer_list)
fn();
You can add functions manually, for example, from int main():
initializer_list.push_back(&Square::init);
...
But I suggest that you need some arhitecture design that will make you able adding functions into initializer list without changing main or any other global code.
To solve this task we can make small helper class that will register your init functions automatically:
struct OpenGLHelper_initializer
{
OpenGLHelper_initializer(std::function<void()> fn)
{
initializer_list.push_back(fn);
}
};
So you can declare instance of this class in your Square/Circle:
struct Square
{
static OpenGLHelper_initializer __initializer;
};
And in your Square.cpp file:
OpenGLHelper_initializer Square::__initializer(&Square::init);
So, when program loads, all this initializer will be constructed and all your "init" function will be registered into initializer_list.
This looks like more code, but it will make you able to add as many shapes as you need without changing Opengl_Initializer::init(); or main.cpp or any other global code
Your can now remove init functions, if you dont like them and use lambdas:
// in square.cpp
OpenGLHelper_initializer Square::__initializer([](){
std::cout << "Square is initialized now" << std::endl;
});
Here is complete source code (Updated with using static function) (but without cpp files - all in one):
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
/////////////////////////////////////////
// opengl_helper.h
// this is some manager class that knows what should be initialized later
struct OpenGLHelper
{
typedef std::function<void()> function_type;
static std::vector<function_type>& get_initialization_list();
static void register_initializer(function_type fn);
static void run_init();
};
// helper class that will register some function at construction time
struct OpenGLHelper_initializer
{
OpenGLHelper_initializer(OpenGLHelper::function_type fn)
{
OpenGLHelper::register_initializer(fn);
}
};
/////////////////////////////////////////
//opengl_helper.cpp
// using this function we will make our initializer_list be constructued
// before adding anything into it
std::vector<OpenGLHelper::function_type>& OpenGLHelper::get_initialization_list()
{
static std::vector<function_type> initializer_list;
return initializer_list;
}
// function that puts initializer into a list.
void OpenGLHelper::register_initializer(OpenGLHelper::function_type fn)
{
get_initialization_list().push_back(fn);
}
void OpenGLHelper::run_init()
{
for (auto fn : get_initialization_list())
fn();
}
/////////////////////////////////////////
// figure.h
// here is sample class that will be registered for initialization
struct Square
{
static int to_be_initialized;
// static member that will register Square class to be initialized
static OpenGLHelper_initializer __initializer;
};
/////////////////////////////////////////
// Square.cpp
int Square::to_be_initialized = 0;
// this is the most interesting part - register square into initializer list
OpenGLHelper_initializer Square::__initializer([](){
Square::to_be_initialized = 15;
std::cout << "Called Square::init: " << to_be_initialized << std::endl;
});
int main()
{
std::cout << "Before initialization : " << Square::to_be_initialized << std::endl;
OpenGLHelper::run_init();
std::cout << "After initialization : " << Square::to_be_initialized << std::endl;
return 0;
}
Output:
Before initialization : 0
Called Square::init: 15
After initialization : 15
Live test
BTW, such way of initialization is used by QT's metatype system - it uses macros to simplify code
UPDATE:
As Ben suggested, we can eliminate small memory leak from bynamic link allocation if we will put initialization list into a static function. Here is new code
I suggest a versioning system, so that initialization can be automatically performed at time-of-use, but in a way that skips it very cheaply when the initialization has already been done. Something like
int global_gl_generation = 0; // increment each time you recreate the context
inline bool check_gl_generation(int& local_generation)
{
if (local_generation == global_gl_generation)
return false;
local_generation = global_gl_generation;
return true;
}
and then in each class,
class Square
{
// static variable all classes have
static int generation_inited;
static GLuint program;
static GLint uniform1;
static GLint uniform2;
static init(const char* shader, const char* frag, const char *camera);
public;
void draw() override
{
if (check_gl_generation(generation_inited)) init(...);
// use program, uniform1, uniform2
}
};
I've been trying desperately to get share a public variable between two classes in C++, but I can't seem to get the hang of it. I've tried getters and setters and calling it directly as a static variable but nothing.
This is what I've tried:
DataGrabber.h
#pragma once
class DataGrabber {
public:
static float temp;
void readProcess(){
temp = 1.2;
}
}
Particle.h
#pragma once
class Particle {
public:
void update() {
float x = DataGrabber::temp;
}
AND THEN THIS:
DataGrabber.h
#pragma once
class DataGrabber {
public:
float temp;
float get(){return temp;}
void readProcess(){
temp = 1.2;
}
}
Particle.h
#pragma once
class Particle {
public:
void update() {
float x = DataGrabber.get();
}
They are both being #include in another main header, testApp.h.
What is the exact problem? How do you use these classes?
Regardless, there are several problems with your getter code.
First, why do you use getter if you make the variable public? If you are going for this design, you should hide the variable as private, to protect it from direct modification.
Second, if it is a simple member variable, you should access it through an object that you pass to your function:
void update(DataGrabber& grabber) {
float x = grabber.get();
}
In this case, you would have to create this object in your main code, which you have not shown.
If you want to use a static variable instead, take a look at a Singleton pattern, but I would advise against it unless there are no better options for your exact problem.
Finally, you should #include all direct dependencies in your header files. Your Particle depends on DataGrabber, so you should include its header from Particle.h. Or, at least, you should add a forward declaration.
For a class, which is only defined in a header, I need a special behavior of one method for all instance of the class. It should be depending on a default value, which can be changed any time during runtime. As I do not want a factory class nor a central management class I came up with that idea:
class MyClass
{
public:
void DoAnything() // Methode which should be act depending on default set.
{
// Do some stuff
if(getDefaultBehaviour())
{
// Do it this way...
}
else
{
// Do it that way...
}
}
static bool getDefaultBehaviour(bool bSetIt=false,bool bDefaultValue=false)
{
static bool bDefault=false;
if(bSetIt)
bDefault=bDefaultValue;
return bDefault;
}
};
It works, but it looks a little awkward. I wonder if there is a better way following the same intention.
In the case where I want to use it the software already created instances of that class during startup and delivered them to different parts of the code. Eventually the program gets the information how to treat the instances (for e.g. how or where to make themselves persistent). This decision should not only affect new created instances, it should affect the instances already created.
I'd advise to use a simple method to simulate a static data member, so the usage becomes more natural:
class MyClass
{
public:
// get a reference (!) to a static variable
static bool& DefaultBehaviour()
{
static bool b = false;
return b;
}
void DoAnything() // Methode which should be act depending on default set.
{
// Do some stuff
if(DefaultBehaviour())
{
// Do it this way...
}
else
{
// Do it that way...
}
}
};
where the user can change the default at any time with
MyClass::DefaultBehaviour() = true;
My thanks to Daniel Frey with his answer which I already marked as the best. I wanted to add my final solution which is based on the answer from Frey. The class is used by some c++ beginners. As I told them to use always getter and setter methods, the way described by Frey looks very complex to beginners ("uuuh, I can give a function a value?!?!"). So I wrote the class like followed:
class MyClass
{
public:
// get a reference (!) to a static variable
static bool& getDefaultBehaviour()
{
static bool b = false;
return b;
}
static void setDefaultBehaviour(bool value)
{
getDefaultBehaviour()=value;
}
void DoAnything() // Methode which should be act depending on default set.
{
// Do some stuff
if(getDefaultBehaviour())
{
// Do it this way...
}
else
{
// Do it that way...
}
}
};
for the user, I looks now like a usual getter and setter.
I have a vector bars that contains several coloured box objects.Each box object has it's own draw and update function. Each box moves from one side of the screen to the next side. when it's outside the screen the box should be removed. I'm using iterators to move the boxes and determine when they are outside of the screen.
I'm very new to c++ and I'm having trouble getting the code to work. the function to erase an object from a vector is giving me the error Reference to non static member function must be called. I'm reading up on static and non static members but I'm still a bit lost.
here's my main header file with the relevant code
class game : public ofxiPhoneApp {
public:
void setup();
void update();
void draw();
void exit();
vector <Colorbar> bars;
bool checkBounds (Colorbar &b);
};
in my game.mm file I create the vector and iterate over it to set the properties of the coloured bar objects:
void game::setup(){
bars.assign(5, Colorbar());
for (int i = 0; i<bars.size(); i++) {
ofColor color = colors.giveColor();
bars[i].setup();
bars[i].setColor(color.r,color.g,color.b);
bars[i].setWidth(50);
bars[i].setPos(ofGetScreenHeight()-(i*50), 0);
}
}
the update function that move the bars across the screen.
void game::update(){
for(vector<Colorbar>::iterator b = bars.begin(); b != bars.end(); b++){
(*b).update();
}
//this is the part that gives the error
bars.erase((remove_if(bars.begin(), bars.end(), checkBounds),bars.end()));
}
and here's the function to check if the box is out of bounds
bool game::checkBounds (Colorbar &b){
if (b.pos.x > ofGetScreenHeight()+50) {
// do stuff with bars vector here like adding a new object
return true;
} else {
return false;
}
}
I've done some experimenting, and making the bool checkBounds (Colorbar &b);
non-static by removing it from the header file makes the code work. but the problem is that I'd also like to be able to access the bars vector in that function to add a new object when an old one is deleted. And that won't work anymore.
How can I solve this?
You need a unary functor taking a ColourBar. A member function has an implicit first parameter for this. This means it cannot be called like this:
Colorbar cb;
game::checkBounds(cb);
It needs to be bound to an instance of its class, otherwise it would not be able to access other members of that instance. So you need to bind the checkBounds member function to an instance of game. In your case, this looks like the right instance to bind:
#include <functional> // for std::bind
using std::placeholders; // for _1
...
remove_if(bars.begin(), bars.end(), std::bind(&game::checkBounds, this, _1)) ...