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

    −40

    1. 1
    *new

    Самая соль.

    Запостил: Говногость, 20 Июня 2012

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

    • Утечка памяти.
      Ответить
      • А может там в каком-нибудь методе delete this есть ? ;)
        Ответить
        • (*new CFoo).Release();

          CFoo *pFoo = &*new CFoo; // заведомо бессмысленно

          Ну, можно, конечно, ссылку инициализировать, типа
          CFoo &f = *new CFoo;
          ...
          delete &f;
          Ответить
          • Как-то так:
            class Foo {
            public:
                void suicide() { delete this; }
                static Foo &create() { return *new Foo(); }
            private:
                Foo();
                ~Foo();
            };
            ...
            Foo &x = Foo::create();
            ... do something with x ...
            x.suicide();

            UPD: Естественно, смысла в этом нет :)
            Ответить
    • Можно контекст?
      Ответить
    • Если new перегружен с каким-нибудь счетчиком созданных объектов - всё OK, но поговорить с автором по душам (по-доброму) всё-таки надо. А то, может, ему общения не хватает.
      Ответить
      • Вы хотели сказать, что new перегружен на возврат умного указателя? Не, это по стандарту не возможно.
        Ответить
        • Сам объект, создаваемый new может иметь функционал умного указателя или тупо хранить в статическом контейнере указатели на созданные объекты, хотя это действительно была глупая идея. А вот передать управление временем жизни другому объекту - уже не выглядит как бред. Так организовали Qt: дочерние виджеты удаляются вместе с их родителями.
          Я всего лишь пытаюсь с оптимизмом посмотреть на этот код :-) TarasB прав, нужно смотреть контекст.
          Ответить
          • А что...
            class MyWidget : QWidget
            {
              ...
              QPushButton &someButton_;
            
              MyWidget( QWidget *parent ) 
                : QWidget(parent), someButton_(*new QPushButton("&Some..."))
              {
                someButton_.setToolTip("Do something");
                ...
              }
            }

            :)
            Ответить
    • показать все, что скрытоКГ/АМ! (спойлер: ОП - ХУЙ!)
      Ответить
    • То чувство когда узнаёшь о какой-то новой неебической хуйне в С++ каждый день.
      Ответить
    • Вопрос стиля на самом деле.

      Мы так регулярно ссылки возвращаем из методов с самодокументирующим (по кодстайлу) названием типа create. RAII, подсчёта ссылок и прочих необходимых по контексту прелестей это не отменяет.

      Возвращение/передача ссылки вместо указателя, в частности, символизирует невозможность NULL (т.е. отсутствие необходимости его проверять на каждом шагу или думать перед вызовом функции, можно ли ей его передать, если очень хочется).
      Ответить
      • > символизирует невозможность NULL
        Скажем мягче - невозможность при вменяемости программиста. Т.к. нехороший человек может намеренно или случайно сделать return *p, где p == NULL и получится нулевая ссылка.
        Ответить
        • Я же написал "символизирует", а не "гарантирует". :) А от невменяемых программистов никакие средства не спасут - с такими просто не нужно работать.

          В любом случае, баги могут быть (и будут) при любом стиле, но ссылка в интерфейсе метода - отличный способ обойтись без лишних комментариев по поводу NULL.
          Ответить
          • Ну да. И еще немаловажна ее иммутабельность.
            Ответить
        • не совсем так
          return *p - заставит убиться прямо тут (если сигналы не ловить, не рассматриваем)
          а вот int & a = a; - как раз невалидная ссылка, которую можно вернуть - получается отложенная пуля в ногу
          Ответить
          • Эм, а можно пруф в стандарте, по которому *p (а не доступ к его полям и методам) выдает исключение или аборт?

            http://ideone.com/2mCis
            Ответить
            • я всегда отталкивался только от использования http://ideone.com/ijx71
              что же, выходит можно возвращать ссылки в виде return *p;
              пруф в стандарте, что можно -
              5.3.1 Unary operators /1
              ... Note: a pointer to an incomplete type (other than cv void ) can be dereferenced.  The lvalue thus obtained
              can be used in limited ways (to initialize a reference, for example); this lvalue must not be converted to an
              rvalue, see 4.1.
              Ответить
              • Что-то ты сегодня не то нашел.
                Тут про incomplete type говорится. Для complete type другое поведение может быть.
                Ответить
                • сегодня?
                  пруф тогда привел неверный - торопился, видать, а найти подходящий пункт в пфд найти не удалось
                  собственно, это, как оказывается, было не так трививально:
                  http://bit.ly/NPeziu
                  http://bit.ly/Hi3Okf
                  Ответить
    • КРИСТЕЦ
      Ответить

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