Initialization of Static Class Variables

Hi all. Long time C programmer here, but just starting to learn C++.

Here’s the situation – I’m developing a class that controls some hardware. The main program can have multiple instances of the class and all instances control the same piece of hardware.

The hardware needs to be initialized before it’s used. That only needs to happen ONCE regardless of the number of class instances there are. So, I figured I’d put that initialization code in the class’s constructor and use a flag to make sure it’s only executed once. I also figured that the flag should be a ‘static’ member variable of the class.

Here’s what I came up with:

Main .ino File:

#include "New_Class.h"

New_Class instance1;
New_Class instance2;

void setup() {
  instance1.doStuff(50);
  instance2.doStuff(175);
}

void loop() {
}

New_Class.h File:

#ifndef _New_Class_h_
#define _New_Class_h_

#include <Arduino.h>

class New_Class
{
    public:
      New_Class();
      void doStuff(uint8_t);

    private:
      static uint8_t hwConfigured;
};
#endif

NewClass.cpp File:

#include "New_Class.h"

uint8_t New_Class::hwConfigured = 0;

New_Class::New_Class() {
  if (!hwConfigured) {
    // Configure the hardware here, only once
    // Set the flag
    hwConfigured = 1;
  }
}

void New_Class::doStuff(uint8_t hwValue) {
  // Use hwValue parameter to cause the hardware to do something
}

Questions:

  1. Generally, is this the “C++ Way” of doing it? If not, what’s better?

  2. I’m a little uncertain about the initialization statement ‘uint8_t New_Class::hwConfigured = 0;’. I don’t know enough C++ yet to fully understand how this initialization interplays with multiple executions of the constructor when multiple class instances are created. I’m thinking the value ‘0’ is just placed in ‘hwConfigured’s’ memory location by the compiler and not touched at run time instantiation. If so, what I have should work, right?

Thanks for your help. Sorry about the long-winded question, but I wanted to described the situation as completely as possible.

It is generally considered that it is not a good idea to do initialisation as part of the constructor as the Arduino hardware may not itself be initialised at that time. It is common for there to be a separate initialisation function in the class that is called from setup(), by which time the Arduino hardware will have been initialised.

As a matter of interest, why have multiple instances of the class if they control the same hardware ?

  1. the line
uint8_t New_Class::hwConfigured = 0;

is completely outside any method. So just like normal global stuff, it’s only done once, at initialization. No matter is you create any New_Class-objects or not.

And if it’s only going to hold two states it would make sense to make it a bool and assign it true or false :).

UKHeliBob:
As a matter of interest, why have multiple instances of the class if they control the same hardware ?

Figured someone would as that (valid) question. I post a great over-simplification of the situation. Call it an SSCCE.
It completely described my issue of concern without getting bogged down in complexity or minutiae.

The SSCCE isn't the problem because it doesn't even show it.

It purely your text which indeed sounds weird. Why have multiple pieces control the same hardware? Doesn't it need governing from something that knows all instances?

OK, maybe I should have stated it a more abstract way.

  • I have a class.

  • The class has a constructor.

  • Each time a new variable of the class is instantiated the constructor will run.

  • When the constructor runs, it needs to know if it’s the very first time it has run or not the very first time.

  • My idea was to use a static class variable as a “first time” flag.

  • The flag variable will be initialized at compile time to a known starting value.

  • When the constructor runs, it checks the flag variable. If the flag contains the starting value, the constructor does some stuff and then sets the flag variable to a different value.

  • Subsequent executions of the constructor will see that the flag variable does not contain the starting value so they will not do the stuff.

I think that @septillion addressed my concern. There is only one flag variable and it’s only initialized once (by the compiler). So, it will not be “re-initialized” each time the constructor runs.

But do note that when you make global objects of your class you have no control over when the constructor is called and which functionality is already initialized.

Noted. Thanks.