1. C++ / Говнокод #2556

    +61.9

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    //Обьявление класса в хедере с последующей реализацией:
    template<class TConstructStrategy>
    class TClass
    {
    public:
    	TConstructStrategy __ctor;
                      //...Прочие методы...
    };
    
    //...Реализация прочих методов класса...
    
    //================================================================
    
    //Конструктор с переменным числом параметров, типа функтор:
    //Тоесть обьявлено где-то в коде проекта и передаётся, как параметр при конструировании.
    typedef void TConstract(int a);
    template<>
    TClass<TConstract>::TClass(int a)
    {
    	//doing...
    };
    
    int main(int argc, char* argv[])
    {
              //...
              TClass<TConstract> A(5);
              //...
    }

    Это говнокод, но не результат работы над проектом, а результат насмешек над компилятором MSVC 6.0.
    Основано на обявлении типа-функции:
    typedef void TConstract(int a);, но тк конструктор не функция - используется внутренее имя конструктора MSVC6.0:
    void __ctor(void);, согласно которому он всё-таки функция.
    __dtor - "внутренее" имя деструктора, кстати.
    Спалить "секретное" имя обычно можно в сообщениях об ошибках c участием этих имён. При входе в конструктор/деструктор через отладчик под дизасемблером(наверное). В стеке вызовов отладчика(наверное). Наверное ещё как-нибудь, например проходом HEX редактора по экзешнику компилятора и прилижащим dll...
    Итак для обсуждения (хотя и не собираюсь это использовать):
    1)Как ещё, кроме странных пергрузок, представленного выше метода конструктора-функтора, и вызовов типа A.__ctor(); / A.__dtor() это можно использовать?
    2)Какие "скрытые" имена конструкторов/деструкторов у других компиляторов? Я пробовал в MSVC6.0. В MSVS 2008 при первом расмотрении "внутреннее" имя другое и сходу не палится.
    Для примера приведу метод с "обычным" функтором (на самом деле он не самый обычный):

    //Обьявление класса в хедере с последующей реализацией:
    template<class TStrategy>
    class TClass
    {
    public:
    TStrategy func;
    //...Прочие методы...
    };

    //...Реализация прочих методов класса...

    //================================================================

    //Функтор:
    //Тоесть обьявлено где-то в коде проекта и передаётся, как параметр при конструировании.
    typedef void TFunc(void);
    template<>
    void TClass<TFunc>::func(void)
    {
    //doing...
    };
    int main(int argc, char* argv[])
    {
    //...
    TClass<TFunc> A;
    A.func();
    //...
    };

    Запостил: fake_guest, 05 Февраля 2010

    Комментарии (19) RSS

    • Пришлось перенести часть описания "говнокода" в комментарий, тк оно не поместилось...
      "Обычный" функтор TClass<TFunc> A; компилируется во многих компиляторах, более или менее соответсвующих стандарту.
      Продолжаем обсуждение, но уже относительно "обычного" функтора(приведенный чуть выше код), тк всерьёз задумываюсь над его использованием :
      3)Это говнокод и использовать его не стоит?
      4)Какие ещё интересные применения можно найти для типов-функций typedef void TFunc(void);?
      Ответить
    • И где тут говнокод?
      Ответить
      • Использование внутреннего имени __ctor конструктора в компиляторе для перегрузки.
        Ответить
    • Чуть не забыл, функтор, как и функтор-конструктор, также с переменным числом параметров.
      Обнаружил ошибочку функтора (в конструкторе она тоже есть). Хотя исправляется легко.
      template<class TStrategy>
      class TClass
      {
      public:
      	TStrategy func;
      };
      
      //Функторы с переменным числом параметров:
      typedef void TFunc(void);
      template<>
      void TClass<TFunc>::func(void)
      {
      	//doing...
      };
      
      
      typedef void TFunc2(void);
      template<>
      void TClass<TFunc2>::func(void)
      {
      	//doing...
      };

      В выше приведённом коде не удаётся обьявить второй функтор с тем же числом параметров в том же CPP-файле. Пишет, что мол уже обьявлен. Исправляеться легко:
      template<class TStrategy>
      class TClass
      {
      public:
      	typename TStrategy::TFunction func;
      };
      
      
      //Функторы с переменным числом параметров:
      struct TFunc
      {
      	typedef void TFunction(void);
      };
      template<>
      void TClass<TFunc>::func(void)
      {
      	//doing...
      };
      
      
      struct TFunc2
      {
      	typedef void TFunction(void);
      };
      template<>
      void TClass<TFunc2>::func(void)
      {
      	//doing...
      };
      	//...
      	TClass<TFunc> A;
      	A.func();
      	TClass<TFunc2> B;
      	B.func();

      Единственное, для различных компиляторов нужно правильно расставить ключевое слово typename. Например, для MSVC6.0 оно вообще не нужно.
      Ответить
    • Не осилил, много букв. Выложи свой опус в каком-нибудь форуме для ботанов
      Ответить
    • Где здесь C++, guest?!
      Ответить
      • Объявляю эту шутку больше не смешной.
        Ответить
      • Удостоверяю. Здесь действительно его нет. __ctor - не С++. ;)
        Ответить
        • Из всего приведенного кода только __ctor показалось похожим на ключевое слово C++? ;-)
          Ответить
      • Предлагаю за немотивированный вопрос "Где здесь C++?" банить по IP. Шутка поднадоела.
        Ответить
    • Матан?
      Ответить
    • За издевательства над компиляторами однозначно +

      Жаль, но такой код не переносим. Почитал стандарт, и вот что там сказано про шаблоны:
      14.3.1/3:
      If a declaration acquires a function type through a type dependent on a template-parameter and this causes a declaration that does not use the syntactic form of a function declarator to have function type, the program is ill-formed. [Example:

      template<class T> struct A {
      static T t;
      };
      typedef int function();
      A<function> a; // ill-formed: would declare A<function>::t
      // as a static member function


      --- end example]

      В переводе на русский - функциональный тип нельзя использовать при объявлении функций в шаблонах. Но можно в обычных классах. Интересно почему именно так?
      Ответить
    • Гражданин, тут теперь форум?
      Ответить
    • тема интересная, но накуя это _здесь_ постить???
      Ответить
    • Ой давайте не будем про MSVC 6.0 оно родилось когда Я ещё в школу ходил. А наш ебанутый заказчик настаивает на том что бы на нём проект писали, ну вот и пишем уже 3- года будет. Вы не видели там мой шаблонный "адоптированый" под древний компилятор код с матюками в коментариях. Хуле там.. заказчик не пробиваемый. А в проекте изменение порядка хидеров например может привести к INTERNAL COMPILER ERROR.
      Поэтому там в инклюд секции так и написано - "не трогай блядь...., я эту причину два дня искал" :-)
      Во общем пора наверно валить с этого проекта, засиделся Я там, да и заказчик не пробиваемый жлоб и идиот.
      Ответить

    Добавить комментарий