ФлеймФорумПрограммирование

RTTI насколько сие необходимо и полезно?

Страницы: 1 2 3 4 Следующая »
#0
19:37, 26 дек 2010

Вот собственно вопрос.
нужно ли вообще RTTI, как сильно оно уменьшает скорость работы программы, и критично ли это уменьшие?
с ним становится легче програмировать, но ведь есть и обратные стороны медали?

#1
20:22, 26 дек 2010

Да. Критично. dynamic_cast где-то в 10 раз тормознее static_cast.

#2
20:36, 26 дек 2010

MAMOHT-92
> с ним становится легче програмировать...
В каком месте?

#3
20:39, 26 дек 2010

Mimon
> В каком месте?

Легче говнокодить.

Ваш К.О.

#4
20:46, 26 дек 2010

Mimon
Нет, ну все ведь хотят прикастить к void*, а потом у этого void* вызвать метод и вообще пошариться внутри.

#5
20:47, 26 дек 2010

вот знаю что в с++ RTTI слабенький и тормознутый.
но вот щас изучил немногно RTTI  в дельфе, клевая вещь, работа с классами облегчается, очень сильно.

#6
20:48, 26 дек 2010

MarkoPolo
> Нет, ну все ведь хотят прикастить к void*, а потом у этого void* вызвать метод
> и вообще пошариться внутри.

А, ты про этих криворуких идиотов? Ну тогда да, им RTTI действительно необходим и полезен )

#7
21:12, 26 дек 2010

Ну раз такая пьянка пошла, одепты 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!

ну и т.д. :-)

#8
21:15, 26 дек 2010

.NightmareZ.
Класс! (= Как я раньше без этого жил???

#9
21:35, 26 дек 2010
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
#10
21:45, 26 дек 2010

.NightmareZ.
Это все-таки reflection, а не RTTI.
И да, идеальный мир без dynamic_cast, а reflection - нужная, полезная и крутая штука, которой C++ лишен

Кстати, весь подобный код с использованием reflection'а перестает работать при обфусцировании кода. Если не запрещать обфускатору трогать определенные методы/классы и тд

#11
21:46, 26 дек 2010

Gordon
> Кстати, весь подобный код с использованием reflection'а перестает работать при обфусцировании кода. Если не запрещать обфускатору трогать определенные методы/классы и тд

Спасибо, Кэп ;-)

#12
21:49, 26 дек 2010

.NightmareZ.
задачи где это нужно на С++ не решаются, для таких задач есть питон...

#13
21:50, 26 дек 2010

Pushkoff
> задачи где это нужно на С++ не решаются, для таких задач есть питон...

Дык о чем и речь. C# универсальный язык, в отличие от....

#14
21:56, 26 дек 2010

Чего опять смешивают в кучу языки разных уровней?

Страницы: 1 2 3 4 Следующая »
ФлеймФорумПрограммирование

Тема в архиве.