C ++: статическая инициализация члена массива, член за раз - PullRequest
4 голосов
/ 27 января 2011

Теперь я могу сделать это в глобальном масштабе, и все работает нормально:

const char* Foo::bars[3] = {"a", "b", "c"};

Но я хочу сделать это, потому что это намного понятнее и самодокументируется (особенно если вы используете Enums в качестве индекса):

const char* Foo::bars[3];
bars[0] = "a";
bars[1] = "b";
bars[2] = "c";

Возможно ли это в любом случае?

Я знаю, что могу сделать это внутри функции (например, конструктора класса), но что, если конструктор не вызывается в начале программы, и я хочу использовать статический массив?Это приводит к проблемам.

Ответы [ 5 ]

7 голосов
/ 27 января 2011

Как насчет этого?

const char* Foo::bars[3] = {
/* Index    Value */
/* 0 */     "a",
/* 1 */     "b",
/* 2 */     "c"
};

Я часто использую эту "технику", чтобы инициализация массивов структур выглядела как самодокументированная электронная таблица.

1 голос
/ 27 января 2011

В C ++ нет эквивалента Java-блока static.

Если вы действительно хотите автоматически инициализировать массив, вы можете создать простой класс для выполнения работы:

// in .cpp
class FooInitializer {
public:
    FooInitializer() {
        Foo:bars[0] = "a";
        Foo:bars[1] = "b";
        Foo:bars[2] = "c";
    }
};

static FooInitializer fooInitializer;
0 голосов
/ 27 января 2011

Возможно, вам нужен дополнительный констант в барах

const char* const Foo::bars[3] = 
{
   "a",
   "b",
   "c"
};

Как вы объявили, вы можете делать то, что хотели, устанавливая членов по одному, хотя вы бы использовали для этого функцию «init».

Если вы хотите, чтобы это const, что, вероятно, предпочтительнее, впоследствии станет недопустимым назначать им строку по очереди, даже в каком-то методе "init", и вам просто нужно использовать макет кода, чтобы сделать его более понятным что ты делаешь.

0 голосов
/ 27 января 2011

Вот еще одно решение, в котором используется шаблон Singleton .Обратите внимание, что массив инициализируется один раз в конструкторе синглтона.Также обратите внимание, что это не потокобезопасно.Также остерегайтесь зла синглетонов (поищите на этом сайте «синглтон», чтобы найти интересные дебаты по этому вопросу).

#include <iostream>

class StringTable
{
public:
    enum StringId
    {
        hello,
        bye,
        goodDay,
        stringCount
    };

    static const char* lookup(StringId id) {return instance().table_[id];}

private:
    StringTable()
    {
        table_[hello] = "Hello World!\n";
        table_[bye] = "Goobye, cruel world!\n";
        table_[goodDay] = "I said good day!\n";
    }

    static StringTable& instance()
    {
        static StringTable theInstance;
        return theInstance;
    }

    const char* table_[stringCount];
};


int main()
{
    std::cout << StringTable::lookup(StringTable::hello)
              << StringTable::lookup(StringTable::bye)
              << StringTable::lookup(StringTable::goodDay);
}
0 голосов
/ 27 января 2011

Вы можете использовать функцию доступа:

const char* GetArray()
{
    static char* result[3];
    static isInitialized = false;
    if (!isInitialized)
    {
        result[0] = "a";
        result[1] = "b";
        result[3] = "c";
        initialized=true;
    }
    return result;
}
...