Инициализация статических элементов класса. (Что-то туплю, никак не соображу - когда?)

Модератор: Модераторы разделов

Аватара пользователя
Zeus
Сообщения: 694

Инициализация статических элементов класса.

Сообщение Zeus »

Есть такой класс:

Код: Выделить всё

class A
{
 public:
 A();
 static std::string type2name (long);
 private:
 static std::map<long,name> _type2name;
}


Предполагается, что можно получить строку по целому значению не создавая экземпляр класса А.
А где тогда заполнить map _type2name?

Пока единственное что приходит в голову - в каждом вызове ф-и type2name проверять: если map пустой, то вызывать функцию его заполнения.
Но что-то не нравится мне такое решение.
Спасибо сказали:
Аватара пользователя
BlackStar
Сообщения: 1338
Статус: We are all Kosh
ОС: Fedora 10

Re: Инициализация статических элементов класса.

Сообщение BlackStar »

Не знаю как в С++, в Java это можно сделать с помощью "статического блока":

Код: Выделить всё

    class Spoon {
      static int i;
      static {
        i = 47;
      }
      // . . .
LightLang Team
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Инициализация статических элементов класса.

Сообщение v04bvs »

Zeus писал(а):
02.08.2007 11:53
Есть такой класс:

Код: Выделить всё

class A
{
 public:
 A();
 static std::string type2name (long);
 private:
 static std::map<long,name> _type2name;
}


Предполагается, что можно получить строку по целому значению не создавая экземпляр класса А.
А где тогда заполнить map _type2name?

Где надо - там и заполни. Что то я не совсем пойму, что ты хочешь. Сделай например статическую функцию A::init и вызывай её в main()-е. Можешь даже автоматический её вызов сделать.

Пока единственное что приходит в голову - в каждом вызове ф-и type2name проверять: если map пустой, то вызывать функцию его заполнения.
Но что-то не нравится мне такое решение.

Можно и так сделать.
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: Инициализация статических элементов класса.

Сообщение Zeus »

v04bvs писал(а):
02.08.2007 13:46
Где надо - там и заполни. Что то я не совсем пойму, что ты хочешь. Сделай например статическую функцию A::init и вызывай её в main()-е.

А если main'а нету.
Если это разделяемая библиотека?
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Инициализация статических элементов класса.

Сообщение v04bvs »

Zeus писал(а):
02.08.2007 14:12
v04bvs писал(а):
02.08.2007 13:46
Где надо - там и заполни. Что то я не совсем пойму, что ты хочешь. Сделай например статическую функцию A::init и вызывай её в main()-е.

А если main'а нету.
Если это разделяемая библиотека?

Смотри:
MyClass a; // объявлена глобальная переменная

конструктор a.MyClass() вызовется перед функцией main, или сразу после загрузки библиотеки. Соответственно туда ты можешь засунуть какой нибудь код инициализации. Как это сделать красивее - смотри сам, можешь с шаблонами поколдовать.
Только имей в виду, что если объявлены 2 переменные в 2 разных модулях, то порядок, в котором вызываются конструкторы не специфицирован.
Ещё в gcc есть __attribute((constructor)) (или что то вроде этого, уже не помню), оно пишется рядом с обычной функцией и означает то же самое. Но это - gcc-specific.
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: Инициализация статических элементов класса.

Сообщение Zeus »

v04bvs писал(а):
02.08.2007 15:23
Смотри:
MyClass a; // объявлена глобальная переменная

С переменной-то и вопросов не возникло бы.
Для этого статические функции и не нужны.
Спасибо сказали:
dronord
Сообщения: 40
ОС: slackware

Re: Инициализация статических элементов класса.

Сообщение dronord »

Создай ещё одну стат. ф-ю, например,

Код:

static A::put2map( long l, string s );
и вызывай в программе до использования этой мапы.
P.S. Только не пойму, зачем здесь static.
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: Инициализация статических элементов класса.

Сообщение Zeus »

dronord писал(а):
02.08.2007 16:37
Создай ещё одну стат. ф-ю, например,

Код:

static A::put2map( long l, string s );
и вызывай в программе до использования этой мапы.

Так где вызывать-то? Если это динамическая библиотека.

dronord писал(а):
02.08.2007 16:37
P.S. Только не пойму, зачем здесь static.

В классе есть "справочные" функции.
Они работают без создания объекта класса.

Вопрос перетекает в разряд досужих - сделал подругому
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Инициализация статических элементов класса.

Сообщение v04bvs »

Код: Выделить всё

class Initializer {
public:
  Initializer() {
    A::initialize();
  }
};

Initializer i;
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: Инициализация статических элементов класса.

Сообщение Zeus »

v04bvs писал(а):
02.08.2007 20:13

Код: Выделить всё

class Initializer {
public:
  Initializer() {
    A::initialize();
  }
};

Initializer i;

Вот, блин, изврат какой! :D
Ну ладно, значит красивого способа инициализировать статические данные нету.
А то я уж думал, что чего-то не понимаю.
Спасибо сказали:
Аватара пользователя
Dockland
Сообщения: 2
ОС: Mandriva

Re: Инициализация статических элементов класса.

Сообщение Dockland »

http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gc...tion-Attributes
http://www.ibm.com/developerworks/eserver/...n32toLinux.html
Т.е. работает как в C++ так и в C.

Код: Выделить всё

extern "C"
void __attribute__((constructor)) whatever_name_init(){}
extern "C"
void __attribute__((destructor)) whatever_fini(){}
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: Инициализация статических элементов класса.

Сообщение Zeus »

Спасибо.
В общем, понятно: наиболее оптимальный переносимый метод - в самОй статической функции проверять неинициализированность данных и инициализировать.
Остальное всё - какие-то навороты или непереносимые решения.

Ну ладно. Всё-равно проблема отпала в процессе решения.
Всем спасибо.
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Инициализация статических элементов класса.

Сообщение v04bvs »

Zeus писал(а):
02.08.2007 20:18
v04bvs писал(а):
02.08.2007 20:13

Код: Выделить всё

class Initializer {
public:
  Initializer() {
    A::initialize();
  }
};

Initializer i;

Вот, блин, изврат какой! :D
Ну ладно, значит красивого способа инициализировать статические данные нету.
А то я уж думал, что чего-то не понимаю.

Почему изврат то?
Можно переформулировать задачу, и вместо std::map<long, name> завести свой класс, который будет инициализироваться в конструкторе. По-моему это оптимальный вариант.
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: Инициализация статических элементов класса.

Сообщение Zeus »

v04bvs писал(а):
03.08.2007 00:11
Можно переформулировать задачу, и вместо std::map<long, name> завести свой класс, который будет инициализироваться в конструкторе. По-моему это оптимальный вариант.

1. Конструктор - значит нужно создавать объект этого класса.
2. Не люблю городить огород из всяких help'еров и т.п. лишних (где они лишние, конечно) классов.
3. Нравится интерфейс контейнеров стандартной библиотеки.
Спасибо сказали: