Reflection, iили подобно, в C++
12 отговора
407 прегледа
Reflection, iили подобно, в C++
Значи, има class factory за клас и наследниците му.
Но бих искал, създаването на наседници да вървин с for по стрингове.
Нещо като reflection в .net
В смисъл,описал съм наследника, и искам да го вкарам само с 1 ред във фабриката, има няколко вида конструктори, но това може да се заобиколи.
???
Но бих искал, създаването на наседници да вървин с for по стрингове.
Нещо като reflection в .net
В смисъл,описал съм наследника, и искам да го вкарам само с 1 ред във фабриката, има няколко вида конструктори, но това може да се заобиколи.
???
Re: Reflection, iили подобно, в C++
Ами в зависимост от конкретния ти случай може и да може да минеш с някаква безумна система от макроси. Но ще трябват минимум два макроса на клас - веднъж в декларацията и веднъж дефиницията. Обикновено минусите от безумните системи макроси са повече от плюсовете. Напиши си го на ръка.
reflection е едно такова нещо дето е практически невъзможно да се добави в език, който го няма - защото не е "синтактична захар" като обектите с методи и ли виртуалните функции например, а връзка между кода от високо ниво и runtime кода, която връзка се губи при компилацията на С++.
Липсата на reflection за мен е най-големият проблем в С++, а не по-често споменаваните калпави exceptions и меко казано странния template синтаксис.
reflection е едно такова нещо дето е практически невъзможно да се добави в език, който го няма - защото не е "синтактична захар" като обектите с методи и ли виртуалните функции например, а връзка между кода от високо ниво и runtime кода, която връзка се губи при компилацията на С++.
Липсата на reflection за мен е най-големият проблем в С++, а не по-често споменаваните калпави exceptions и меко казано странния template синтаксис.
Re: Reflection, iили подобно, в C++
Пълен reflection в C++ е малко невъзможна работа... Има правени доста опити, но не знам някой да е успял напълно. В Boost се дискутираше въпроса по едно време покрай serialization библиотеката им, но не успяха да измислят свестен и достатъчно общ дизайн.
Ако обаче всичко, което ти трябва, е просто конструиране на обект, по името на класа, това е достатъчно лесно и без reflection. Можеш да си напишеш собствено RTTI, по-мощно от вграденото в езика, което да поддържа и конструиране по име. Skotowydec в общи линии е казал как става с двата макроса. Използваш времето, когато се инициализират статичните променливи, преди main(), и тогава си генерираш структурите. Можеш да ползваш имената на класовете като ключове в хеш таблица, аз навремето бях писал такова RTTI.
Ако обаче всичко, което ти трябва, е просто конструиране на обект, по името на класа, това е достатъчно лесно и без reflection. Можеш да си напишеш собствено RTTI, по-мощно от вграденото в езика, което да поддържа и конструиране по име. Skotowydec в общи линии е казал как става с двата макроса. Използваш времето, когато се инициализират статичните променливи, преди main(), и тогава си генерираш структурите. Можеш да ползваш имената на класовете като ключове в хеш таблица, аз навремето бях писал такова RTTI.
Re: Reflection, iили подобно, в C++
Използваш времето, когато се инициализират статичните променливи, преди main()...
И много внимаваш с този момент, защото ще имаш проблеми, и после още проблеми, и после и проблемите ти ще имат проблеми, и после ще скърпиш положението с няколко if( g_bOtherSubsystemAlreadyBooted ) и ще забравиш за 6 месеца за тях докато не добавиш някоя библиотека в проекта, или ще смениш компилатора, или ще сложиш друг memory manager, и тотално ще се разбърка реда на инициализиране на глобални/статични променливи и пак ще се почне...
Тая тема започва да ми прилича на "10-те ми любими неща в С++" :-)
И много внимаваш с този момент, защото ще имаш проблеми, и после още проблеми, и после и проблемите ти ще имат проблеми, и после ще скърпиш положението с няколко if( g_bOtherSubsystemAlreadyBooted ) и ще забравиш за 6 месеца за тях докато не добавиш някоя библиотека в проекта, или ще смениш компилатора, или ще сложиш друг memory manager, и тотално ще се разбърка реда на инициализиране на глобални/статични променливи и пак ще се почне...
Тая тема започва да ми прилича на "10-те ми любими неща в С++" :-)
Re: Reflection, iили подобно, в C++
Много ясно че внимаваш в този момент :-) Естествено че трябва да се има предвид, че реда на инициализация на статичните променливи в отделните модули не е дефиниран (стандартът гарантира правилен ред само вътре в модула). В моя случай избегнах този проблем, като разчитах на друго нещо, което стандартът гарантира - а то е, че преди да започне инициализацията, всички глобални променливи се нулират. Като се има предвид това, става относително лесно, още повече че инициализацията става в една нишка.
Re: Reflection, iили подобно, в C++
Хмм. А какво ако добавим custom build стъпка - едно AWK или Perl да парсват .h файловете и да генерират макросите? Някой не го ли е пробвал това?
I am a death dealer. Е така де вампирите по ме накефиха.
I am a death dealer. Е така де вампирите по ме накефиха.
Re: Reflection, iили подобно, в C++
Казват по мейлинг листовете някакви хора че са го пробвали, пак има проблеми. Макросите са си макроси какъвто и да е препроцесора :-) Ти пишеш един код, а компилатора чете друг.
Вместо да се изнасилва декларативната природа на декларациите на класове, някои използват за подобни цели процедурно описание на член-данните на класа - точно таково процедурно описание е функцията-сериализатор
Например, ако имаш система при която клас се сериализира с такава функция:
void CFoo::Persist(PersistStream& ps)
{
Persist(m_nWidth, "width"); // да се чете като "имам тук един инт и му викам width", а не като "запиши ей този инт"
Persist(m_nHeight, "height");
Persist(m_strCaption, "caption");
}
това може да се използва четене/запис на обекти от класа в някакъв формат, но може да се използва и за други неща, които на език с рефлексия би постигнал с рефлексия - например дъмпване на логове, редактиране през автоматично изграждан юзер интерфейс, хеширане и т.н.
Вместо да се изнасилва декларативната природа на декларациите на класове, някои използват за подобни цели процедурно описание на член-данните на класа - точно таково процедурно описание е функцията-сериализатор
Например, ако имаш система при която клас се сериализира с такава функция:
void CFoo::Persist(PersistStream& ps)
{
Persist(m_nWidth, "width"); // да се чете като "имам тук един инт и му викам width", а не като "запиши ей този инт"
Persist(m_nHeight, "height");
Persist(m_strCaption, "caption");
}
това може да се използва четене/запис на обекти от класа в някакъв формат, но може да се използва и за други неща, които на език с рефлексия би постигнал с рефлексия - например дъмпване на логове, редактиране през автоматично изграждан юзер интерфейс, хеширане и т.н.
Re: Reflection, iили подобно, в C++
> Казват по мейлинг листовете някакви хора че са го пробвали, пак има
> проблеми. Макросите са си макроси какъвто и да е препроцесора :-)
> Ти пишеш един код, а компилатора чете друг.
Може би не описах достатъчно подробно това което имам впредвид. Идеята ми е следната - както си има описание на клас в .h файла:
MyClass.h:
class MyClass{
public:
int A;
float B;
};
специална стъпка преди компилацията обхожда тези .h файлове и генерира макроси в някакъв .h файл, примерно:
reflection_data.h:
DECLARE_CLASS ("MyClass")
DECLARE_MEMBERVAR ("A")
DECLARE_MEMBERVAR ("B")
END_DECLARE_CLASS
Така се гарантира синхрон между макросите и самия клас. Реализирането на такава стъпка е много лесно с AWK или Perl. Стъпката може да генерира и код подобен на този който си описал:
void MyClass::Persist(PersistStream& ps)
{
Persist(A, "A");
Persist(B, "B");
}
I am a death dealer. Е така де вампирите по ме накефиха.
> проблеми. Макросите са си макроси какъвто и да е препроцесора :-)
> Ти пишеш един код, а компилатора чете друг.
Може би не описах достатъчно подробно това което имам впредвид. Идеята ми е следната - както си има описание на клас в .h файла:
MyClass.h:
class MyClass{
public:
int A;
float B;
};
специална стъпка преди компилацията обхожда тези .h файлове и генерира макроси в някакъв .h файл, примерно:
reflection_data.h:
DECLARE_CLASS ("MyClass")
DECLARE_MEMBERVAR ("A")
DECLARE_MEMBERVAR ("B")
END_DECLARE_CLASS
Така се гарантира синхрон между макросите и самия клас. Реализирането на такава стъпка е много лесно с AWK или Perl. Стъпката може да генерира и код подобен на този който си описал:
void MyClass::Persist(PersistStream& ps)
{
Persist(A, "A");
Persist(B, "B");
}
I am a death dealer. Е така де вампирите по ме накефиха.
Re: Reflection, iили подобно, в C++
> Тая тема започва да ми прилича на "10-те ми любими неща в С++" :-)
10 любими класически кошмара в програмирането
I am a death dealer. Е така де вампирите по ме накефиха.
10 любими класически кошмара в програмирането
I am a death dealer. Е така де вампирите по ме накефиха.
Re: Reflection, iили подобно, в C++
Хората са разгледали различни подходи, категоризирали са предимствата и недостатъците. Доста хубава статия, още повече че предлагат и готово решение.
I am a death dealer. Е така де вампирите по ме накефиха.
I am a death dealer. Е така де вампирите по ме накефиха.
Re: Reflection, iили подобно, в C++
Под "ти пишеш един код, а компилаторът чете друг" имах предвид, че например не можеш да сложиш точка на прекъсване в генерираното - така както и с макросите. И ще е доста трудно да направиш системата typesafe - на практика трябва да направиш истински парсер на С++, което ще те погребе млад :-)
Re: Reflection, iили подобно, в C++
Аааа, тая работа в рефлексията не е кошмар по нормалните езици. С#-хората правят много интересни неща с метаданните си.