Reflection, iили подобно, в C++

12 отговора 407 прегледа
#1

Reflection, iили подобно, в C++

Значи, има class factory за клас и наследниците му.
Но бих искал, създаването на наседници да вървин с for по стрингове.
Нещо като reflection в .net

В смисъл,описал съм наследника, и искам да го вкарам само с 1 ред във фабриката, има няколко вида конструктори, но това може да се заобиколи.

???

Отговор
в отговор на Pia #2

Re: Reflection, iили подобно, в C++

Ами в зависимост от конкретния ти случай може и да може да минеш с някаква безумна система от макроси. Но ще трябват минимум два макроса на клас - веднъж в декларацията и веднъж дефиницията. Обикновено минусите от безумните системи макроси са повече от плюсовете. Напиши си го на ръка.

reflection е едно такова нещо дето е практически невъзможно да се добави в език, който го няма - защото не е "синтактична захар" като обектите с методи и ли виртуалните функции например, а връзка между кода от високо ниво и runtime кода, която връзка се губи при компилацията на С++.

Липсата на reflection за мен е най-големият проблем в С++, а не по-често споменаваните калпави exceptions и меко казано странния template синтаксис.

Отговор
в отговор на Skotowydec #3

Re: Reflection, iили подобно, в C++

Пълен reflection в C++ е малко невъзможна работа... Има правени доста опити, но не знам някой да е успял напълно. В Boost се дискутираше въпроса по едно време покрай serialization библиотеката им, но не успяха да измислят свестен и достатъчно общ дизайн.

Ако обаче всичко, което ти трябва, е просто конструиране на обект, по името на класа, това е достатъчно лесно и без reflection. Можеш да си напишеш собствено RTTI, по-мощно от вграденото в езика, което да поддържа и конструиране по име. Skotowydec в общи линии е казал как става с двата макроса. Използваш времето, когато се инициализират статичните променливи, преди main(), и тогава си генерираш структурите. Можеш да ползваш имената на класовете като ключове в хеш таблица, аз навремето бях писал такова RTTI.

Отговор
в отговор на Pesho® #4

Re: Reflection, iили подобно, в C++

Използваш времето, когато се инициализират статичните променливи, преди main()...

И много внимаваш с този момент, защото ще имаш проблеми, и после още проблеми, и после и проблемите ти ще имат проблеми, и после ще скърпиш положението с няколко if( g_bOtherSubsystemAlreadyBooted ) и ще забравиш за 6 месеца за тях докато не добавиш някоя библиотека в проекта, или ще смениш компилатора, или ще сложиш друг memory manager, и тотално ще се разбърка реда на инициализиране на глобални/статични променливи и пак ще се почне...

Тая тема започва да ми прилича на "10-те ми любими неща в С++" :-)

Отговор
в отговор на Skotowydec #5

Re: Reflection, iили подобно, в C++

Много ясно че внимаваш в този момент :-) Естествено че трябва да се има предвид, че реда на инициализация на статичните променливи в отделните модули не е дефиниран (стандартът гарантира правилен ред само вътре в модула). В моя случай избегнах този проблем, като разчитах на друго нещо, което стандартът гарантира - а то е, че преди да започне инициализацията, всички глобални променливи се нулират. Като се има предвид това, става относително лесно, още повече че инициализацията става в една нишка.

Отговор
в отговор на Skotowydec #6

Re: Reflection, iили подобно, в C++

Хмм. А какво ако добавим custom build стъпка - едно AWK или Perl да парсват .h файловете и да генерират макросите? Някой не го ли е пробвал това?

I am a death dealer. Е така де вампирите по ме накефиха.
Отговор
в отговор на Пepин #7

Re: Reflection, iили подобно, в C++

Казват по мейлинг листовете някакви хора че са го пробвали, пак има проблеми. Макросите са си макроси какъвто и да е препроцесора :-) Ти пишеш един код, а компилатора чете друг.

Вместо да се изнасилва декларативната природа на декларациите на класове, някои използват за подобни цели процедурно описание на член-данните на класа - точно таково процедурно описание е функцията-сериализатор

Например, ако имаш система при която клас се сериализира с такава функция:

void CFoo::Persist(PersistStream& ps)
{
Persist(m_nWidth, "width"); // да се чете като "имам тук един инт и му викам width", а не като "запиши ей този инт"
Persist(m_nHeight, "height");
Persist(m_strCaption, "caption");
}

това може да се използва четене/запис на обекти от класа в някакъв формат, но може да се използва и за други неща, които на език с рефлексия би постигнал с рефлексия - например дъмпване на логове, редактиране през автоматично изграждан юзер интерфейс, хеширане и т.н.

Отговор
в отговор на Skotowydec #8

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. Е така де вампирите по ме накефиха.
Отговор
в отговор на Skotowydec #9

Re: Reflection, iили подобно, в C++

> Тая тема започва да ми прилича на "10-те ми любими неща в С++" :-)

10 любими класически кошмара в програмирането

I am a death dealer. Е така де вампирите по ме накефиха.
Отговор
в отговор на Пepин #10

Re: Reflection, iили подобно, в C++

Tova vizdali li ste go?
[линк]

Отговор
в отговор на dummy #11

Re: Reflection, iили подобно, в C++

Хората са разгледали различни подходи, категоризирали са предимствата и недостатъците. Доста хубава статия, още повече че предлагат и готово решение.

I am a death dealer. Е така де вампирите по ме накефиха.
Отговор
в отговор на Пepин #12

Re: Reflection, iили подобно, в C++

Под "ти пишеш един код, а компилаторът чете друг" имах предвид, че например не можеш да сложиш точка на прекъсване в генерираното - така както и с макросите. И ще е доста трудно да направиш системата typesafe - на практика трябва да направиш истински парсер на С++, което ще те погребе млад :-)

Отговор
в отговор на Пepин #13

Re: Reflection, iили подобно, в C++

Аааа, тая работа в рефлексията не е кошмар по нормалните езици. С#-хората правят много интересни неща с метаданните си.

Отговор