Нужно программно инициализировать массив переменных класса, как лучше это сделать? - PullRequest
2 голосов
/ 24 августа 2011

В C ++ у меня есть массив значений типа double, которые необходимо программно инициализировать, во время выполнения, только один раз, чтобы весь класс мог делиться ими. Они могут быть как статическими, так и постоянными. Как лучше всего их инициализировать? Я отказался от использования статики с огромной популярностью параллельных процессоров, в настоящее время проникающих. Так должен ли я установить флаг для однократного запуска или есть какая-то статическая константная магия, которая инициализирует их как переменную, локальную для функции (хорошо) или класса (тоже хорошо)?

    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;

В приведенном выше коде я хотел бы сделать weightAtI поиском с каждым двойным числом, уже разделенным на sumOfWeights, чтобы я мог получить их, не просматривая NUMTRACES.

_ EDIT _ Это нормально, для этого и нужны конструкторы :) Просто надеясь, что мои сделки с статикой, константой и инициализацией вступят в сделку. Спасибо, Сет

_ EDIT _ Не уверен, что это именно тот эффект, который я хотел. Конструктор работает на каждом экземпляре, даже если члены статические, нет? Лемм смотри ...

_ EDIT _ Я думаю, что наиболее эффективным решением является защита цикла инициализатора статическим флагом в конструкторе. Будучи флагом POD, я уверен, что он должен вести себя должным образом, я просто не совсем уверен, что это на данном этапе.

_ EDIT _ Ааа, понял:

class X
{
public:
    static int i;
};
int X::i = 0; // definition outside class declaration

_ EDIT _ К сожалению, когда дело доходит до моего кода,

    static const int MIDTRACE = 3;
    static const int NUMTRACES = 2 * MIDTRACE + 1;
    static double WEIGHTATI[NUMTRACES];

Я получаю ошибки компоновщика:

meobj.obj: ошибка LNK2020: неразрешенный токен (0A00001C) "private: static double * mens: meclass :: PIMPL :: WEIGHTATI" (? WEIGHTATI @ PIMPL @ meclass @ mens @@ $$ Q0PANA) meobj.obj: ошибка LNK2001: неразрешенный внешний символ "private: static double * mens: meclass :: PIMPL :: WEIGHTATI" (? WEIGHTATI @ PIMPL @ meclass @ mens @@ $$ Q0PANA)

из-за моего конструктора:

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;
    }
}

Ответы [ 2 ]

2 голосов
/ 24 августа 2011

Initialization => конструктор.Once => статический экземпляр.Так что одним из способов является статический экземпляр чего-то с конструктором.

#include <iostream>

struct Foo
{
    Foo()
    {
        std::cout << "Initializing them values..." << std::endl;
        for( int i = 0;  i < 3;  ++i )
        {
            values[i] = i;
        }
    };

    int values[3];
};

void doThings()
{
    static Foo const    foo;        // Is initialized ONCE.

    for( int i = 0;  i < 3;  ++i )
    {
        std::cout << foo.values[i] << " ";
    }
    std::cout << std::endl;
}

int main()
{
    doThings();
    doThings();
    doThings();
}

Приветствия & hth.,

1 голос
/ 24 августа 2011

Вы можете установить флаг static bool в своем конструкторе.Флаг будет инициализирован на false только при первом вызове.После этого оно останется истинным.

// foo.h

class Foo {
  static const int MIDTRACE = 3; // static const, no definition needed
  static const int NUMTRACES = 2 * MIDTRACE + 1; // static const, no definition needed
  static double WEIGHTATI[NUMTRACES]; // not const, so need definition outside of class
public:
  Foo() {
    static bool array_initialized = false;
    if( !array_initialized ) {
      // Initialize array
      array_initialized = true;
    }
  }
  // Other members
};

В исходном файле, а не в заголовочном файле:

// foo.cpp
include "foo.h"
double Foo::WEIGHTATI[NUMTRACES];
...