Вызов инициализирующего кода вне конструктора
От: glap  
Дата: 02.10.13 21:06
Оценка: -1
САБЖ. Нужно для привязывания переменных и геттеров/сеттеров к их строковому эквиваленту времени исполнения.

Пример:

class A
{
  int member0;
  int member1;
  int member2;
  SOMETHING_COOL(member0)
  SOMETHING_COOL(member1)
  SOMETHING_COOL(member2)
};



Решение пока через класс с конструктором по умолчанию.

#define SOMETHING_COOL(...) \
struct UNIQ_NAME  \
{  \
    UNIQ_NAME() \
    { \
         тут делаем что нужно; \
    } \
} uniq_member_name;



Всё бы ничего, но на каждый пустой тип выделяется 1 байт. Штука активно используется для связывания статики и динамики в большом проекте с глубокой иерархией классов и на эти однобайтовые красивости куча памяти уходит. Нахожусь в поисках решения чтобы сильно не пришлось портить устоявшийся интерфейс.

П.С.
C++0x11 не доступен.
Re: Вызов инициализирующего кода вне конструктора
От: watchmaker  
Дата: 02.10.13 22:25
Оценка:
Здравствуйте, glap, Вы писали:

G>Всё бы ничего, но на каждый пустой тип выделяется 1 байт. Штука активно используется для связывания статики и динамики в большом проекте с глубокой иерархией классов и на эти однобайтовые красивости куча памяти уходит. Нахожусь в поисках решения чтобы сильно не пришлось портить устоявшийся интерфейс.

Так непонятно почему бы просто вызов SOMETHING_COOL не перенести в конструктор класса A? Или тебе всё же нужно и в деструкторе вспомогательного класса какие-то действия совершать? Ну тогда можно сделать чтобы один класс от другого наследовался. В идеале сделать класс A наследником такой иерархии — любой современный компилятор позаботится чтобы пустые базовые классы в этом случае никакой памяти не занимали.
Re: Вызов инициализирующего кода вне конструктора
От: Erop Россия  
Дата: 03.10.13 02:09
Оценка:
Здравствуйте, glap, Вы писали:

G>САБЖ. Нужно для привязывания переменных и геттеров/сеттеров к их строковому эквиваленту времени исполнения.


G>
G>class A
//...
G>#define SOMETHING_COOL(...) \
G>struct UNIQ_NAME  \
G>{  \
G>    UNIQ_NAME() \
G>    { \
G>         тут делаем что нужно; \
G>    } \
G>} uniq_member_name; 
G>



А делать "что нужно" надо для каждого класса А или для каждого экземпляра каждого класса А?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Вызов инициализирующего кода вне конструктора
От: Кодт Россия  
Дата: 03.10.13 08:09
Оценка:
Здравствуйте, glap, Вы писали:

G>САБЖ. Нужно для привязывания переменных и геттеров/сеттеров к их строковому эквиваленту времени исполнения.


Такой дизайн устроит?
class A
{
  int member0;
  int member1;
  int member2;

  SOMETHING_COOL_BEGIN(A)      // A() {
    SOMETHING_COOL(member0)    //   .....
    SOMETHING_COOL(member1)    //   .....
    SOMETHING_COOL(member2)    //   .....
  SOMETHING_COOL_END()         // }
};

Максимум, 1 байт на член-хелпер, а минимум — 0 байт на инлайн-определение функции (например, конструктора).
Перекуём баги на фичи!
Re[2]: Вызов инициализирующего кода вне конструктора
От: glap  
Дата: 03.10.13 13:39
Оценка:
Это близко к тому к чему я склоняюсь. Правда придётся как-то так:

SOMETHING_COOL_SCOPE(      
    SOMETHING_COOL(member0),   
    SOMETHING_COOL(member1),   
    SOMETHING_COOL(member2)   
 )



Один SOMETHING_COOL не только код инициализации наращивает, но и одну-две функции-помощника создаёт в A.

В целом не плохо. Жаль, что похоже нет варианта вообще не менять интерфейс классов...
Re[2]: Вызов инициализирующего кода вне конструктора
От: glap  
Дата: 03.10.13 13:42
Оценка:
Здравствуйте, Erop, Вы писали:


E>А делать "что нужно" надо для каждого класса А или для каждого экземпляра каждого класса А?


Для каждого класса А. В конструкторе UNIQ_NAME есть проверка было ли это действие уже произведено.
Re[2]: Вызов инициализирующего кода вне конструктора
От: glap  
Дата: 03.10.13 13:44
Оценка:
Здравствуйте, Кодт, Вы писали:

К>
К>class A
К>{
К>  int member0;
К>  int member1;
К>  int member2;

К>  SOMETHING_COOL_BEGIN(A)      // A() {
К>    SOMETHING_COOL(member0)    //   .....
К>    SOMETHING_COOL(member1)    //   .....
К>    SOMETHING_COOL(member2)    //   .....
К>  SOMETHING_COOL_END()         // }
К>};
К>


Ну и конечно конструктор класса нельзя занимать.
Re[3]: Вызов инициализирующего кода вне конструктора
От: Erop Россия  
Дата: 04.10.13 10:06
Оценка: 2 (1)
Здравствуйте, glap, Вы писали:

G>Для каждого класса А. В конструкторе UNIQ_NAME есть проверка было ли это действие уже произведено.


тогда можно пойти по такому пути:
template<void (*It)()> class CallItOnce {
    static struct Caller {
        Caller() { It(); }
    } callIt;
    const char dummy;
public:
    CallItOnce() : dummy( (char)&callIt ) {}  // хак, что бы гарантировать инстанциацию соответствующего шаблона.
};

template<void (*It)()> CallItOnce<It> CallItOnce<It>::callIt;

// пример:
class AZZ {
    static int count;
    // Это собственно то, что будет генериться внутри твоего макроса
    static void initializer() {
        CallItOnce<&initializer> callIt; // продолжение того же хака.
        count++;
    }
public:
    static int Get(){ return count; }
};
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Вызов инициализирующего кода вне конструктора
От: glap  
Дата: 04.10.13 12:38
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, glap, Вы писали:


G>>Для каждого класса А. В конструкторе UNIQ_NAME есть проверка было ли это действие уже произведено.


E>тогда можно пойти по такому пути: ...


Отлично! Спасибо.
Re[5]: Вызов инициализирующего кода вне конструктора
От: Erop Россия  
Дата: 04.10.13 18:06
Оценка:
Здравствуйте, glap, Вы писали:

E>>тогда можно пойти по такому пути: ...


G>Отлично! Спасибо.


Не за что, обращайся.
p. s.
Для "спасибо" тут есть кнопки
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Вызов инициализирующего кода вне конструктора
От: glap  
Дата: 17.08.14 19:51
Оценка:
Интересно почему этот приём не работает с шаблонными классами для каждой инстанциации. MSVC.
Отредактировано 17.08.2014 19:53 glap . Предыдущая версия .
Re[4]: Вызов инициализирующего кода вне конструктора
От: Vain Россия google.ru
Дата: 17.08.14 20:48
Оценка:
Здравствуйте, Erop, Вы писали:

G>>Для каждого класса А. В конструкторе UNIQ_NAME есть проверка было ли это действие уже произведено.

E>тогда можно пойти по такому пути: [c]template<void (*It)()> class CallItOnce {
E> static struct Caller {
E> Caller() { It(); }
E> } callIt;
E> const char dummy;
E>public:
E> CallItOnce() : dummy( (char)&callIt ) {} // хак, что бы гарантировать инстанциацию соответствующего шаблона.
E>};
Использование статических мемберов — плохой тон. Можно ненароком шмальнуть себе по ноге из конструктора такого же статического объекта.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: Вызов инициализирующего кода вне конструктора
От: Abyx Россия  
Дата: 17.08.14 20:52
Оценка:
Здравствуйте, glap, Вы писали:

G>П.С.

G>C++0x11 не доступен.
что если С++17 не доступен, то уж 14 или 11-то доступны? так там NSDMI есть
In Zen We Trust
Re[5]: Вызов инициализирующего кода вне конструктора
От: Erop Россия  
Дата: 17.08.14 21:01
Оценка:
Здравствуйте, Vain, Вы писали:


V>Использование статических мемберов — плохой тон. Можно ненароком шмальнуть себе по ноге из конструктора такого же статического объекта.


Вообще инициализации где-то кроме глобальной функции инициализации -- дурной тон.
Но конкретно тут, как планируется шмалять?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: Вызов инициализирующего кода вне конструктора
От: Vain Россия google.ru
Дата: 17.08.14 23:59
Оценка:
Здравствуйте, Erop, Вы писали:

V>>Использование статических мемберов — плохой тон. Можно ненароком шмальнуть себе по ноге из конструктора такого же статического объекта.

E>Вообще инициализации где-то кроме глобальной функции инициализации -- дурной тон.
E>Но конкретно тут, как планируется шмалять?
Как обычно делают? Обычно деляют либо инициализацию по вызову функции со статической переменной, либо, ещё лучше, явную инициализацию всего одним явным вызовом по принципу "либо всё, либо ничего", чтобы можно было перенести/пересортировать вызовы различных инициализаций в нужном месте. Такое если выстрелет, то сразу в голову без всяких прилюдий.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[7]: Вызов инициализирующего кода вне конструктора
От: Erop Россия  
Дата: 18.08.14 06:38
Оценка:
Здравствуйте, Vain, Вы писали:

E>>Но конкретно тут, как планируется шмалять?

V>Как обычно делают? Обычно деляют либо инициализацию по вызову функции со статической переменной, либо, ещё лучше, явную инициализацию всего одним явным вызовом по принципу "либо всё, либо ничего", чтобы можно было перенести/пересортировать вызовы различных инициализаций в нужном месте. Такое если выстрелет, то сразу в голову без всяких прилюдий.

Про то, что явной функцией приложение инициализировать лучше, я не спорю.
Но это вопрос архитектуры приложения, а не тот, который задал ТС...

И таки да, как в данном конкретном случае планируется шмалять?..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[8]: Вызов инициализирующего кода вне конструктора
От: Vain Россия google.ru
Дата: 18.08.14 06:40
Оценка:
Здравствуйте, Erop, Вы писали:

E>И таки да, как в данном конкретном случае планируется шмалять?..

Я ж ответил — явной инициализацией.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[9]: Вызов инициализирующего кода вне конструктора
От: Erop Россия  
Дата: 18.08.14 06:45
Оценка:
Здравствуйте, Vain, Вы писали:

E>>И таки да, как в данном конкретном случае планируется шмалять?..

V>Я ж ответил — явной инициализацией.

Имелось в виду "шмалять в ногу".
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: Вызов инициализирующего кода вне конструктора
От: glap  
Дата: 18.08.14 10:19
Оценка:
Здравствуйте, Vain, Вы писали:

V>Здравствуйте, Erop, Вы писали:


V>>>Использование статических мемберов — плохой тон. Можно ненароком шмальнуть себе по ноге из конструктора такого же статического объекта.

E>>Вообще инициализации где-то кроме глобальной функции инициализации -- дурной тон.
E>>Но конкретно тут, как планируется шмалять?
V>Как обычно делают? Обычно деляют либо инициализацию по вызову функции со статической переменной, либо, ещё лучше, явную инициализацию всего одним явным вызовом по принципу "либо всё, либо ничего", чтобы можно было перенести/пересортировать вызовы различных инициализаций в нужном месте. Такое если выстрелет, то сразу в голову без всяких прилюдий.

Наверное надо отталкиваться от задачи, а не от каких-то эфемерных подводных камней. Моя задача так решается и избавляет меня от необходиомости для каждого класса, коих больше сотни, писать инициализацию из другого модуля. Забыть её сделать реальная опасность, а ваша выдуманная, т.к. вне контекста.
Re[2]: Вызов инициализирующего кода вне конструктора
От: glap  
Дата: 18.08.14 10:22
Оценка:
Здравствуйте, Abyx, Вы писали:

A>Здравствуйте, glap, Вы писали:


G>>П.С.

G>>C++0x11 не доступен.
A>что если С++17 не доступен, то уж 14 или 11-то доступны? так там NSDMI есть

За что минус влепил? Ещё и бред какой-то написав в ответ.
Мне недоступен современный цпп. Тебе очень интересно причина или к чему это написано?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.