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

    +18

    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
    template <typename Derived>
    class Base {
    public:
    	void doSmth() {
    		// ...
    		static_cast<Derived*>(this)->OnParseAndHandle();
    		//...
    	}
    };
    
    class MyClass: public Base<MyClass> {
    public:
    	void OnParseAndHandle() {
    		// ...
    	}
    };

    Если Вы не верите в виртуальные методы, то шаблоны Вам в помощь.

    А может я идиот и чего-то не понял?

    Запостил: benderlog, 26 Января 2013

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

    • Довольно известный прием. Почитать о нем можно, например, вот здесь http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern или вот тут http://blog.aaronballman.com/2011/08/static-polymorphism-in-c/. Еще, если не ошибаюсь (давно читал), его часто юзал Александреску на страницах своей книги Modern c++ design.

      Плюсы по сравнению с виртуальными методами - нет оверхеда в рантайме, можно применять и к статическими методам.
      Минусы - не может выбирать нужный метод в рантайме, и немного странно смотрится.
      Ответить
      • Спасибо
        таки и есть, что я идиот и не понял
        Ответить
        • Говно в этом коде прячится только в том случае, если звбыли проверить в Base::doSmth, что typeid(this)==typeid(Derived)
          Ответить
          • стасик здесь стоит как раз за тем, чтобы время сэкономить, а не проигрывать виртуальному вызову
            а множественное наследование (ты же это имел в виду?) создаст проблемы не всегда, но об этом неплохо бы знать, да
            Ответить
            • Что ты там о множественном наследовании писал?

              Я имею ввиду вот это:
              class MyClassDerived: public Base<MyClass>
              или
              class MySomeOtherClass: public Base<MyClass>


              >стасик здесь стоит как раз за тем, чтобы время сэкономить
              Так точно, капитан! assert ещё ни кому не мешал экономить время
              Ответить
              • Для простоты продемонстрирую:
                assert(typeid(this)==typeid(Derived));
                Ответить
            • множественное наследование - это я ляпнул не подумав спросонья
              компилятор корректно пересчитывает this при даункасте

              про ассерт понятно
              Ответить
      • Гы %) Вот тут и вспомнилось, как в универе заставляли делать список литературы. Надо ввести в обиход.
        Ответить
        • Ага... допустим возникает желание написать кому-то "Ты хуй!". Но нельзя же запостить это без списка литературы, так что в итоге эта фраза будет оформляться как-то так:

          Ты хуй! [1][2]
          1) http://lurkmore.to/%D0%A2%D1%8B_%D1%85%D1%83%D0%B9
          2) http://ru.wikipedia.org/wiki/%D0%A5%D1%83%D0%B9


          А что... по крайней мере это выглядит серьезно и научно.

          P.S. Никогда не любил составлять списки использованной литературы в универе, т.к. была проблема - эту самую литературу я почти не использовал, а ссылки у нас не особо любили.
          Ответить
          • >lurkmore
            ноу вэй
            Ответить
            • Ты забыл список литературы:
              1) http://www.urbandictionary.com/define.php?term=no%20way
              2) http://lurkmore.to/%D0%9D%D0%B5%D1%82_%D0%BF%D1%83%D1%82%D0 %B8
              Ответить
              • >уёбдикшинари
                Ты меня убедил
                Ответить
                • > Ты меня убедил
                  Опять забыл список литературы[1]?

                  1) http://narfu.ru/agtu/www.agtu.ru/fad08f5ab5ca9486942a52596ba6582elit.html
                  Ответить
    • О, цээртэпэшечка!
      Ответить
      • Как гласит украинская вики - дивно рекурсивний шаблон.
        Ответить
    • а в базовом классе определен виртуальный OnParseAndHandle?
      Ответить
      • Из комментария к посту можно заключить, то нет.
        Ответить
      • Смысл был в том, чтобы избавится от виртуального вызова, а ты его суда приплел. Нет конечно.
        Ответить
      • Нет конечно. Если интересно как работает это крестоблядство - прочти ссылки в моем комменте в самом вверху.
        Ответить
        • значит говно - предок не должен знать о детях
          Ответить
          • Это неявный контракт, они повсюду в TMP
            Ответить
          • Вы ничего не понимаете
            Ответить
            • Ты же не собрался гнать его за это из професии? Вот смотрю я на тебя: совсем ты окрестоблядился.
              Ответить
              • Причем окрестоблядиться Тарас умудрился на платформе, на которой обычно становятся жавоебами (у меня вот, походу, от общения с данной платформой началась мутация в жавоеба).
                Ответить
                • Лучше быть крестоблядью, чем жабой.
                  Ответить
                  • >Лучше быть крестоблядью
                    Фу, Тарас. Как тебе не стыдно.
                    И поцеловал он жабу, но превратилась она не в красавицу-принцессу, а в страшную стерву-крестоблядь.
                    И жили они долго, но несчастливо - с постоянным непониманием и багами.
                    И подумал кодер: "Уж лучше б осталась ты жабой".
                    После свежих откровений С++11 предсказуемая, читабельно-унылая жаба смотрится куда лучше.
                    Ответить
          • А он и не знает почти ничего о детях. Собственно о ребенке он знает ровно столько же, сколько знал бы, если бы там был виртуальный метод - у ребенка есть метод void OnParseAndHandle(), на этом его знания заканчиваются.
            Ответить
    • Годная вещь. Мне лично в плюсах не хватает скаловских примесей
      http://ideone.com/dEJ1ew
      Ответить
      • В языке D есть traits, но помоему он сейчас есть даже в пхп.
        Конкретно по тому что ты сделал смотри boost::operators и std::rel_ops
        Ответить

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