Why declare variables in header?

Hello, I’ve just started working through the examples in the OF book, and in this section, when it gets to using polylines, the author begins to define variables in the header file, rather than in the ofApp.cpp file as was done up to that point. I’m guessing the reason is explained in more detail later on, but can anyone give me a basic explanation as to when it’s best to define variables in the header and when not to?

Thanks

the simplest answer is variables declared in the header file are accessible outside the class (if also marked public)

Very simply put, and yes, I’m oversimplifying here and talking only about variables without going into how compilers work and preprocessor macros and so forth - this has to do something with something called scope.

When you say int myNumber or declare any other variable within a function/anywhere, it’s only available between the { before it and } after it. If something is defined in the header file, it is, however, available all throughout your c++ file. When you’re defining it in the header file, it’s called a global variable and in the other case, it’s a local variable. Another thing to keep in mind, is the fact that the update/draw loop is running at 60 fps (or similar) and defining a variable within this scope will always reset it to whatever you declaration is. When it’s a global variable, however, it can change across the entire life cycle of the application.

Below, some examples,

if you do

ofApp::update(){
    int myRadius = 100;
}

ofApp::draw(){
    ofDrawCircle(0, 0, myRadius); //ERROR! myRadius is not defined within this scope.
}

versus,

//in .h
int myRadius;

//.cpp
ofApp::setup(){
    myRadius = 100;
}

ofApp::draw(){
   ofDrawCircle(0, 0, myRadius); //no issues here :slight_smile: 

Second example,

void ofApp::update(){
    int myNumber = 100;
    cout << myNumber << endl; //prints 100
    myNumber++;
    cout << myNumber << endl; //prints 101

This above block of code will ALWAYS print 100, 101 and then again 100, 101.
Versus,

//in .h
int myNumber;

//in .cpp
ofApp::setup(){
   myNumber = 100;
    cout << myNumber << endl; //prints 100.
}

ofApp::update(){
    muNumber++;
    cout << myNumber << endl; //prints 101, then 102, 103... for every frame.
}
2 Likes

Makes sense, thanks!

In practice then, is defining variables within update() or draw() fairly rare? Other than to take advantage of that reseting, when is it useful to do so?

It’s not rare, but it definitely depends on the use case. I’m assuming you’re new to C++/openFrameworks so I don’t want to confuse you at the outset and understanding when to use what will come with practise and more experience.

One of the most common ways to use local variables is to do some quick math to keep things legible. Imagine you have two global variables, input1 and input2, both in the range of 0-100. Now you want to use the average of the two to set the radius of a circle. One of the ways to do it would be to do ofDrawCircle(x, y, (input1 + input2)/2); Now, this is a simple case, but imagine more complex mathematics. You could easily break it down into,

int radius = (input1 + input2)/2;
ofDrawCircle(x, y, radius);

or even break it down more to,

int total = input1 + input2;
int average = total/2;

ofDrawCircle(x, y, average);

Now imagine you wanted to draw the circle within the range of 0 -7365. You’d want to use the ofMap function using the average and it can get really ugly really soon doing ofDrawCircle(x, y, ofMap((input1 + input2)/2, 0, 100, 0, 7365)); where if you had the local variable radius or average, it would be a much nicer and readable bit of code

//case 1:
int radius = (input1 + input2)/2;
int drawRadius = ofMap(radius, 0, 100, 0, 7365);
ofDrawCircle(x, y, drawRadius);

//case 2:
int total = input1 + input2;
int average = total/2;

int drawRadius = ofMap(average, 0, 100, 0, 7365);

ofDrawCircle(x, y, drawRadius);

In these above cases, your variables would not be required outside of this scope, so it would be the perfect time to use them. There are some other use cases for local variables as well, but as I said earlier, I don’t want to confuse you in case you’re a beginner and this would probably be one of the simplest ways of using local variables when starting out.

2 Likes