#c #static-initialization #static-initializer #static-array
#c #статическая инициализация #статический инициализатор #статический массив
Вопрос:
У меня есть статический массив указателей на функции в качестве члена класса.
Мне нужно его инициализировать, но оказывается, что этот массив состоит из 64 КБ элементов, поэтому инициализировать его статическим инициализатором типа { x, y, z, ... }
нецелесообразно, поскольку это загромождало бы код.
Вместо этого я должен инициализировать его кодом с несколькими циклами.
Я решил сделать это, инициализировав static
массив в конструкторе и установив для него флаг, так что только создание первого экземпляра класса приведет к запуску этой инициализации.
Также доступ к этому статическому флагу из экземпляров не был бы потокобезопасным, но это уже другая история.
Есть ли более чистый или лучший способ сделать это?
Я также хотел бы, чтобы этот массив был const
, но, боюсь, единственный способ сделать это — с static {}
инициализацией, верно?
Комментарии:
1. 64 тысячи функций? Кроме того, как вы можете сделать это в цикле, если у каждой функции есть имя?
2. Генерация кода, чувак. Perl, python, что угодно.
3. Мне действительно интересно, как вы собираетесь получить адреса всех этих функций без того же беспорядка, что и с
{ amp;nitializer, amp;lists }
? AFAIK C не имеет отражения?4. @Nikolai да, вы правы, я думал о том, чтобы сделать это в отдельном файле #included
5. @Seth нет, массив содержит 64 тысячи элементов, а тип массива — указатель на функцию, так что это 65536 указателей на функции. Существует около 8 уникальных функций, на которые массив будет указывать в соотношении N к 1.
Ответ №1:
Другим вариантом было бы использовать генерацию кода: написать отдельную программу, которая генерирует исходный код для определения статического массива.
Ответ №2:
Возможно, не самый чистый код, но как насчет того, чтобы сделать массив-элемент статической ссылкой;
заголовочный файл:
class MyClass
{
...
static const std::vector<pointer to member>amp; pointer_vector;
};
файл реализации:
namespace
{
typedef std::vector<pointer to member> t_pointer_vector;
t_pointer_vector pointer_vector;
const t_pointer_vectoramp; initialize_pointer_vector(void)
{
//generate pointer_vector
return pointer_vector;
}
}
t_pointer_vecotoramp; MyClass::pointer_vector = initialize_pointer_vector();
Если вы не хотите std::vector
, вы можете взглянуть на std::tr1::array
, массив фиксированного размера, который безопаснее и не менее эффективен, чем массив в стиле C (согласно Boost doc). Это часть TR1. Основную информацию о TR1 можно найти в википедии, ее документации в разделе Boost.
Комментарии:
1. спасибо, но поскольку это должен быть фиксированный массив из 65536 элементов и прямой произвольный доступ, поэтому нет необходимости в std::vector.