2013-04-14 3 views
1

Я реализовал функцию быстрого сравнения, которая использует справочную таблицу. Поскольку эта функция используется в нескольких классах проекта, мне нужно убедиться, что во время всего выполнения программы есть только одна копия справочной таблицы.Использование глобального вектора в C++

Таблица поиска - это простой vector<int> размером 65536. Я хочу, чтобы эта таблица была инициализирована в начале программы, а не во время ее первого использования. Как справиться с этой проблемой?

Следующий фрагмент кода - это текущая версия моей функции сравнения. Я считаю, что статическая переменная, ставящая lookup_table, проблема будет разрешена только частично, потому что время жизни статических переменных начинается с того момента, когда поток программы встречается с объявлением.

int fast_compare(const char* array1, const char* array2, int length) 
{ 
    static const vector<int> lookup_table = init_lookup_table(); 

    // process the input arrays... 
    // ... 
    return lookup_table[...]; 
} 

vector<int> init_lookup_table() 
{ 
    vector<int> lut(65536); 

    // ---------------------------- 
    // initialize the look-up table 
    // ... 
    // ... 
    // end of initialization 
    // ---------------------------- 

    return lut; 
} 
+1

Если вы знаете размер во время компиляции, вы можете извлечь выгоду из использования 'станд :: array' вместо' станд :: VECTOR'. –

+1

Объявление 'lut' как переменной' static' в функции 'fast_compare' сделает его более потокобезопасным. Вы можете перенести переменную с вызовом функции при запуске, если вам требуется предсказуемое время выполнения. –

+0

Мой комментарий к thread-safty относится только к C++ 11, см. Пункт 6.7.4. –

ответ

2

То, что вы описали это Singleton узор. В Интернете есть документация о том, как синглтон обычно реализуется с помощью C++.

В основном это небольшой класс, который несет статическую функцию, которая возвращает указатель/ссылку на таблицу поиска (я лично предпочитаю ссылки).

Ссылка: Singleton: How should it be used

Однако, более простое решение для конкретной задачи может быть просто сгенерировать таблицу поиска один раз, затем руки boost::shared_pointer сек вокруг.

+0

Хорошо, но как обеспечить, чтобы поисковая таблица была выделена до ее использования? Если эта таблица очень большая, то первый вызов функции 'fast_compare()' может выполняться медленно, потому что таблица будет выделена при первом обращении к объявлению программы. Я хочу, чтобы таблица была назначена раньше первого вызова 'fast_compare()'. – enzom83

+1

Вы всегда можете сделать один запрос в начале и не использовать результат этого запроса. Или вы можете попробовать статическую переменную класса. – ypnos

5

Желательно, чтобы эта таблица была инициализирована в начале программы, а не во время ее первого использования.

Почему бы не использовать неименованное пространство имен в файле cpp?

#include <numeric> 
#include <iterator> 
#include <iostream> 
#include <vector> 

namespace { 
    //c++11 version 
    static auto const lookup_table = []() -> std::vector<int> { 
     std::vector<int> lut(65536); 
     iota(begin(lut), end(lut), 0);// init lut here 
     return lut; 
    }();// invoke the lambda 

    //c++ 98 version 
    //static const std::vector<int> lookup_table = init_lookup_table(); 
} 

int main() 
{ 
    std::cout<<"lut[32768] = " << lookup_table[32768]<<std::endl; 
} 

инициализации лямбда объясняется Herb Sutter here

+0

Красивый современный материал. Признаться, я не понимаю дерьма. – ypnos

+1

@ypnos Я добавил версию C++ 98. Преимущество лямбда заключается в том, что у вас нет функции * named *, а всего лишь блока кода инициализации, связанного с глобальным. –