Вызов инициализирующего кода вне конструктора
От: 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 есть

За что минус влепил? Ещё и бред какой-то написав в ответ.
Мне недоступен современный цпп. Тебе очень интересно причина или к чему это написано?
Re[5]: Вызов инициализирующего кода вне конструктора
От: Chorkov Россия  
Дата: 18.08.14 11:13
Оценка: 1 (1)
Здравствуйте, glap, Вы писали:

G>Интересно почему этот приём не работает с шаблонными классами для каждой инстанциации. MSVC.


Потому что MSVC интсанционирует только те члены шаблонного класса, которые где-либо вызываются.
Метод initializer вызывается исключительно сам из себя.
Ваш Кэп.
Re[6]: Вызов инициализирующего кода вне конструктора
От: glap  
Дата: 18.08.14 11:18
Оценка:
Здравствуйте, Chorkov, Вы писали:

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


G>>Интересно почему этот приём не работает с шаблонными классами для каждой инстанциации. MSVC.


C>Потому что MSVC интсанционирует только те члены шаблонного класса, которые где-либо вызываются.

C>Метод initializer вызывается исключительно сам из себя.
C>Ваш Кэп.

Да, точно. Там же у них самодеятельность народная.
Re[3]: Вызов инициализирующего кода вне конструктора
От: Abyx Россия  
Дата: 18.08.14 13:09
Оценка:
Здравствуйте, glap, Вы писали:

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


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


G>>>П.С.

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

G>За что минус влепил? Ещё и бред какой-то написав в ответ.

G>Мне недоступен современный цпп. Тебе очень интересно причина или к чему это написано?

ну да, ты написал что тебе не доступен С++17.
ок, но есть же предыдущие версии, например С++11
In Zen We Trust
Re[4]: Вызов инициализирующего кода вне конструктора
От: watchmaker  
Дата: 18.08.14 13:34
Оценка: 1 (1) +1 :)
Здравствуйте, Abyx, Вы писали:

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


G>>>>C++0x11 не доступен.


G>>За что минус влепил? Ещё и бред какой-то написав в ответ.


A>ну да, ты написал что тебе не доступен С++17.


А-ха-ха. Если посчитать, что число в подстроке C++0x11 записано в 16-ричной системе счисления, то получится C++17 в десятичной. Отличная шутка! Зануда.
Re[8]: Вызов инициализирующего кода вне конструктора
От: Vain Россия google.ru
Дата: 18.08.14 18:48
Оценка:
Здравствуйте, glap, Вы писали:

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

G>Наверное надо отталкиваться от задачи, а не от каких-то эфемерных подводных камней. Моя задача так решается и избавляет меня от необходиомости для каждого класса, коих больше сотни, писать инициализацию из другого модуля. Забыть её сделать реальная опасность, а ваша выдуманная, т.к. вне контекста.
Ну вот кожда ногу себе прострелишь, вот тогда и подхрамывай на форум.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[9]: Вызов инициализирующего кода вне конструктора
От: glap  
Дата: 18.08.14 19:57
Оценка:
Здравствуйте, Vain, Вы писали:

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


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

G>>Наверное надо отталкиваться от задачи, а не от каких-то эфемерных подводных камней. Моя задача так решается и избавляет меня от необходиомости для каждого класса, коих больше сотни, писать инициализацию из другого модуля. Забыть её сделать реальная опасность, а ваша выдуманная, т.к. вне контекста.
V>Ну вот кожда ногу себе прострелишь, вот тогда и подхрамывай на форум.

А ещё очень опасно использовать операцию деления. Коварный ноль смотрит на деление в твоём коде с ухмылкой. Когда прострелите себе ногу, не приходите на форум, лечите ногу.
Re[10]: Вызов инициализирующего кода вне конструктора
От: Vain Россия google.ru
Дата: 19.08.14 07:47
Оценка:
Здравствуйте, glap, Вы писали:

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

G>>>Наверное надо отталкиваться от задачи, а не от каких-то эфемерных подводных камней. Моя задача так решается и избавляет меня от необходиомости для каждого класса, коих больше сотни, писать инициализацию из другого модуля. Забыть её сделать реальная опасность, а ваша выдуманная, т.к. вне контекста.
V>>Ну вот кожда ногу себе прострелишь, вот тогда и подхрамывай на форум.
G>А ещё очень опасно использовать операцию деления. Коварный ноль смотрит на деление в твоём коде с ухмылкой. Когда прострелите себе ногу, не приходите на форум, лечите ногу.
деление на ноль не вызывает расстрел памяти
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[11]: Вызов инициализирующего кода вне конструктора
От: jazzer Россия Skype: enerjazzer
Дата: 19.08.14 08:12
Оценка: :)
Здравствуйте, Vain, Вы писали:

V>деление на ноль не вызывает расстрел памяти


array[a/b] = 3.1415;

jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[12]: Вызов инициализирующего кода вне конструктора
От: Vain Россия google.ru
Дата: 19.08.14 22:20
Оценка:
Здравствуйте, jazzer, Вы писали:

V>>деление на ноль не вызывает расстрел памяти

J>
J>array[a/b] = 3.1415;
J>

J>
Это не настоящий "расстрел памяти". Настоящий это когда переменная мусором инициализирована в релизе.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.