Вот собственно вопрос.
нужно ли вообще RTTI, как сильно оно уменьшает скорость работы программы, и критично ли это уменьшие?
с ним становится легче програмировать, но ведь есть и обратные стороны медали?
Да. Критично. dynamic_cast где-то в 10 раз тормознее static_cast.
MAMOHT-92
> с ним становится легче програмировать...
В каком месте?
Mimon
> В каком месте?
Легче говнокодить.
Ваш К.О.
Mimon
Нет, ну все ведь хотят прикастить к void*, а потом у этого void* вызвать метод и вообще пошариться внутри.
вот знаю что в с++ RTTI слабенький и тормознутый.
но вот щас изучил немногно RTTI в дельфе, клевая вещь, работа с классами облегчается, очень сильно.
MarkoPolo
> Нет, ну все ведь хотят прикастить к void*, а потом у этого void* вызвать метод
> и вообще пошариться внутри.
А, ты про этих криворуких идиотов? Ну тогда да, им RTTI действительно необходим и полезен )
Ну раз такая пьянка пошла, одепты C++ могут мне рассказать, как на C++ делать что-то подобное (и возможно ли это вообще)?
Допустим, есть у меня класс с конструктором и несколькими методами:
class Test { public Test() { Console.WriteLine( "This is constructor."); } public void Method1( ) { Console.WriteLine( "First method."); } public void Method2( ) { Console.WriteLine( "Second method."); } }
Я могу получить список всех его методов:
Type t = typeof (Test); foreach ( MethodInfo method in t.GetMethods( )) Console.WriteLine( method.Name);
Будет выведено (часть методов унаследована от System.Object):
Method1 Method2 ToString Equals GetHashCode GetType
Либо так:
Type t = typeof (Test); foreach ( MethodInfo method in t.GetMethods( BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public)) Console.WriteLine( method.Name);
Будет выведено:
Method1 Method2
Или вот так вызвать случайный public метод у объекта:
var rnd = new Random(); var test = new Test( ); MethodInfo[] methods = typeof( Test).GetMethods( BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public); methods[rnd.Next( methods.Length)].Invoke( test, null);
Могу получить список конструкторов таким же образом:
ConstructorInfo[] constructors = typeof (Test).GetConstructors( );
А потом создавать объекты динамически (не дёргая руками new, не имея на руках собсна типа):
constructors[0].Invoke(null);
А можно пойти дальше и подключить к этому делу DLR:
dynamic dynamicObject = constructors[0].Invoke(null);
И делать вот так:
dynamicObject.Method1(); dynamicObject.Method2( );
Хотя на этапе компиляции тип не известен.
Можно сделать даже так:
dynamicObject.BlaBla();
или вот так:
dynamicObject = dynamicObject + dynamicObject;
И получить эксепшн во время выполнения, потому что метод BlaBla и оператор + в классе Test не определён.
Но это не критично. Унаследуем класс Test от DynamicObject и будем ловить обращения к несуществующим методам:
class Test : DynamicObject { public Test() { Console.WriteLine( "This is constructor."); } public void Method1( ) { Console.WriteLine( "First method."); } public void Method2( ) { Console.WriteLine( "Second method."); } public override bool TryInvokeMember( InvokeMemberBinder binder, object[] args, out object result) { Console.WriteLine( "Member '{0}' not exists!", binder.Name); result = null; return true; } }
и теперь вызов
dynamicObject.BlaBla();
приведёт к выводу в консоль:
Member 'BlaBla' not exists!
ну и т.д.
.NightmareZ.
Класс! (= Как я раньше без этого жил???
class Writer : DynamicObject { public Writer() { } private readonly string _str; private Writer( string str) { _str = str; } public override bool TryGetMember( GetMemberBinder binder, out object result) { result = new Writer( _str + " " + binder.Name); return true; } public override bool TryInvokeMember( InvokeMemberBinder binder, object[] args, out object result) { Console.WriteLine( _str + " " + binder.Name); result = null; return true; } }
Создаём объект:
dynamic writer = new Writer();
Пишем:
writer.Give.me.the.money();
Получаем в консоли:
Give me the money
.NightmareZ.
Это все-таки reflection, а не RTTI.
И да, идеальный мир без dynamic_cast, а reflection - нужная, полезная и крутая штука, которой C++ лишен
Кстати, весь подобный код с использованием reflection'а перестает работать при обфусцировании кода. Если не запрещать обфускатору трогать определенные методы/классы и тд
Gordon
> Кстати, весь подобный код с использованием reflection'а перестает работать при обфусцировании кода. Если не запрещать обфускатору трогать определенные методы/классы и тд
Спасибо, Кэп
.NightmareZ.
задачи где это нужно на С++ не решаются, для таких задач есть питон...
Pushkoff
> задачи где это нужно на С++ не решаются, для таких задач есть питон...
Дык о чем и речь. C# универсальный язык, в отличие от....
Чего опять смешивают в кучу языки разных уровней?
Тема в архиве.