In C++ I have an array of doubles which need initialising programmatically, at run time, just once, for the whole class to share. They could be both static and constant. How best can I initialise them? I have gone off using static with the prodigious popularity of parrallel processors presently pervading. So must I set a flag to run once or is there some static const magic which will initialise them as a variable local to a function (ok) or class (ok too)?
double sumOfWeights = 0.0;
double fracObs = 0.0;
for (int i = 0; i < NUMTRACES; i++) {
double weightAtI = SQUARED(1 - SQUARED(MAXTRACEWRTMIDTRACE * (MIDTRACE - i)
/ double(MIDTRACE)));
sumOfWeights += weightAtI;
fracObs += obsArray[i] * weightAtI;
}
return fracObs / sumOfWeights;
In the code above I’d like to make weightAtI a lookup with each double already divided by sumOfWeights so I can retrieve them without iterating through NUMTRACES.
_EDIT_
It’s okay, that’s what constructors are for 🙂
Just hoping to tackle my static, const and initialization gremlins into the bargain. Thanks Seth
_EDIT_
Not sure it is quite the effect I wanted though. The constructor runs on each instance, even if the members are static, no? No. Lemme see…
_EDIT_
I think the most efficient solution, is to guard the initializer loop with a static flag, in the constructor. Being a POD flag I’m sure it should behave appropriately, I’m just not quite sure what that is at this stage.
_EDIT_
Ahh, got it:
class X
{
public:
static int i;
};
int X::i = 0; // definition outside class declaration
_EDIT_
Unfortunately, when it comes to my code,
static const int MIDTRACE = 3;
static const int NUMTRACES = 2 * MIDTRACE + 1;
static double WEIGHTATI[NUMTRACES];
I get linker errors:
meobj.obj : error LNK2020: unresolved token (0A00001C) “private: static double * mens:meclass::PIMPL::WEIGHTATI” (?WEIGHTATI@PIMPL@meclass@mens@@$$Q0PANA)
meobj.obj : error LNK2001: unresolved external symbol “private: static double * mens:meclass::PIMPL::WEIGHTATI” (?WEIGHTATI@PIMPL@meclass@mens@@$$Q0PANA)
due to my constructor:
meclass::PIMPL() {
if (!doneStaticInit) {
double sumOfWeights = 0.0;
for (int i = 0; i < NUMTRACES; i++) {
WEIGHTATI[i] = SQUARED(1 - SQUARED(MAXTRACEWRTMIDTRACE * (MIDTRACE - i) / double(MIDTRACE)));
sumOfWeights += WEIGHTATI[i];
}
for (int i = 0; i < NUMTRACES; i++) WEIGHTATI[i] /= sumOfWeights;
doneStaticInit = true;
}
}
You can put a
static boolflag in your constructor. The flag will only be initialized tofalsethe first time it is called. After that it will remain true.In a source file, not header file: