C++ Tutorial
C++ Static
static on a class member is shared by every object. static on a local persists between calls.
One keyword, two jobs
static on a class member means there is one copy for the whole class, not one copy per object.static on a local variable inside a function means the variable is initialized once and then keeps its value across later calls. Same word. Different places. Different lifetimes.
This chapter does not cover static at file scope (internal linkage). The two uses below are the ones you hit first in classes and helpers. StudyGrid compiles the examples as C++17.
A class member shared by every object
Put static int count in the class. Every object reads and writes that same integer. Use it for a running total of how many objects exist, or how many tickets were issued. You still need a definition outside the class: the declaration inside is not storage by itself in C++17.
Example
#include <iostream>
using namespace std;
class Guest {
public:
static int count;
Guest() {
count++;
}
};
int Guest::count = 0;
int main() {
Guest a;
Guest b;
Guest c;
cout << Guest::count << endl;
cout << a.count << endl;
return 0;
}Output is 3 twice. Three constructors ran. There is still only one count.Guest::count is the usual way to read it. a.count is allowed and names the same integer; it does not mean “count for object a”.
Define the static member once
The line int Guest::count = 0; belongs in a source file, outside the class, after the class definition. Skip it and the linker complains that count is undefined. Initialize it to a known value. Zero is the usual start for a counter.
Ordinary members such as a name or an id stay per object. The constructor can set those as usual. Only thestatic field is shared. Mixing both is normal: each guest has its own data, and the class tracks how many guests were built.
A static member function
A method marked static has no this. It can use static members. It cannot use ordinary fields, because there may be no object. Call it on the class: Guest::howMany(). You can call it before any object exists.
Example
#include <iostream>
using namespace std;
class Guest {
public:
static int count;
Guest() {
count++;
}
static int howMany() {
return count;
}
};
int Guest::count = 0;
int main() {
cout << Guest::howMany() << endl;
Guest a;
Guest b;
cout << Guest::howMany() << endl;
return 0;
}Output is 0 then 2. The first call happens with no Guest objects at all.
A static local keeps its value
Inside a function, static int n = 0; is initialized the first time execution reaches that line. Later calls skip the initializer and see the old value. That is how a helper can hand out 1, then 2, then 3 without a global sitting in the open.
Example
#include <iostream>
using namespace std;
int nextSeat() {
static int n = 0;
n++;
return n;
}
int main() {
cout << nextSeat() << endl;
cout << nextSeat() << endl;
cout << nextSeat() << endl;
return 0;
}Output is 1, 2, 3. An ordinary local int n = 0; would reset every call and print 1 three times. The static local lives until the program ends.
Class static versus function static
| static member | static local | |
|---|---|---|
| Where you write it | Inside a class | Inside a function |
| How many copies | One for the class | One for that function |
| Who can see it | As public or private allows | Only that function |
| Needs an out-of-class definition | Yes for this int in C++17 | No |
Neither kind is a substitute for passing arguments. Use a static member when the data belongs to the type. Use a static local when one function must remember a little state and you do not want a class yet.
Do not hide all state this way
Hidden counters make tests harder: the next call depends on every call that already happened. For a tutorial counter they are clear. For application data, prefer an object you can construct, reset, and pass in.
Compile at /cpp/try. Next: abstract classes, where a base type has a function with no body and you only build the derived types.
Worked examples
The short listings above are there so you can see the grammar. The programs here use the same statements on quantities that already have units: a speed, a pH, a count of bases. They are classroom numbers. Air resistance is ignored. g is 9.81 m/s² unless a line says otherwise.
Open them in the C++ editor at /cpp/try. Change one measurement and check whether the result still has the right unit.
Physics
How many field readings
A Hall probe might report tesla. 12 mT, 14 mT, 13 mT are three samples of a weak field (Earth’s field is ~50 µT, so this is a lab magnet). static int n inside the function counts calls. main does not own the counter.
Example
#include <iostream>
using namespace std;
void log_reading(double tesla) {
static int n = 0;
n++;
cout << "reading " << n << ": " << tesla << " T" << endl;
}
int main() {
log_reading(0.012);
log_reading(0.014);
log_reading(0.013);
return 0;
}Biology
How many Sample objects
static on a class member is shared by every object. Two Sample constructions make count 2. That is not the mass of either sample; it is how many exist.
Example
#include <iostream>
using namespace std;
class Sample {
public:
static int count;
Sample() { count++; }
};
int Sample::count = 0;
int main() {
Sample a, b;
cout << Sample::count << endl;
return 0;
}