Куча говна / Говнокод #27000 Ссылка на оригинал

0

  1. 1
Какой багор )))

Запостил: MOXHATKA MOXHATKA, (Updated )

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

  • Петухи, подскажите ламеру. Этот вопрос обсуждался наверняка.

    В крестах у меня полетело исключение из середины конструктора. Это значит, что объект как-бы наполовину сконструирован. Но десктрутор же его не вызовется?
    Как мне очистить ресурсы?

    Допустим, я в конструкторе создал какую-то структуру операционной системы:
    PETUH_HANDLE CreatePetuh();

    Теперь я должен сделать ReleasePetuh(); Но на следующем шаге полетело исключение.

    Я не могу релизнуть петуха -- деструктор не вызывается.

    Я могу вынести конечно питуха в отдельный класс, но не хочу.

    Как верно поступить?

    Я могу конечно не делать этого в конструкторе: просто инициализировать питуха nullptrом, и установить его в каком-то методе типа Initialize()

    Но не хочу.

    Как правильнее поступить?
    Ответить
    • Да, деструктор самого класса не запустится т.к. он недостроился и разрушать нечего.

      Но у локалок деструктор сработает. У полей, которые успели создаться - тоже. Ну и у базовых классов.

      Поэтому складывай всё что насоздавал сразу в RAII'шную хуйню в локалках или в полях. И всё будет норм.
      Ответить
      • >Поэтому складывай всё что насоздавал сразу в RAII'шную хуйню в локалках или в полях.

        Завернуть каждый PETUH_HANDLE в отдельный класс?
        Ответить
    • 1) использовать try catch в конструкторе
      2) использовать инициализацию для полей - для них вызовется деструктор (напиши класс scoped_handle или вообще используй средства shared/unique ptr для нетривиальных способов деструкции)
      Ответить
      • >1) использовать try catch в конструкторе
        Тогда как я сообщу вызывающей стороне, что создать объект не удалось? По какому-то булеву полю?

        > использовать инициализацию для полей
        Так поле же у меня просто поинтер или вообще инт: это или хендл структуры оперционки (сишного API) или смещение в таблице дескрипторов моего процесса, в общем внешний НЕ RAII
        ресурс
        >scoped_handle
        вот сюда посмотрю, спасибо
        Ответить
        • >"Тогда как я сообщу вызывающей стороне, что создать объект не удалось? По какому-то булеву полю?"

          Не ебу в "C++", но, исходя из опыта разработки на "PHP", предлагаю перед "try" создать переменную типа "objectCreated" со значением "false", а внутри "try" присваивать ей значение "true".
          Ответить
          • спасибо. тоже про это подумал
            Ответить
        • > как я сообщу вызывающей стороне, что создать объект не удалось

          У тебя же исключение вылетело. Вызывающий код твой недостроенный объект никогда не увидит.
          Ответить
        • Ты должен подчистить за собой как минимум, и раз уж ты пошел по скользкому пути ебошить исключения в конструкторе - то можно наконец делать throw и из своего, чтобы охуел уже тот, кто пытается твой класс юзать
          Ответить
          • Я понял, да. Спасибо.
            В общем я всё сам почистил, и потом их бросил.

            А как не бросать исключения? Делать тупой конструктор, и всю логику уносить в метод типа Initialize() ?
            Ответить
            • > Делать тупой конструктор, и всю логику уносить в метод типа Initialize() ?

              Да, но лучше брось. Впизду эту джхвухфазную инициализацию, с ней всегда куча ёбли и багров. Её не от хорошей жизни делают.
              Ответить
              • Да у меня-то подгорает от такой инициализации, потому что во-первых лишние действия, во-вторых объект получается может находиться в двух состояниях, и все мутабл.

                Потом еще вон булево поле завозить objectCreated (как советует ротоёб)
                Ответить
                • >Потом еще вон булево поле завозить objectCreated

                  Оно так мешает?
                  Ответить
                  • Ну лучше все таки чтобы объект полностью инициализировался в конструкторе

                    Типа раз есть объект -- значит он инициализирован

                    Хотя для двухфазной инициализации оно ок
                    Ответить
                • > объект получается может находиться в двух состояниях

                  В этом и жопа. Куча возможностей для отстрела яиц - забыл позвать инит, забыл обработать ошибку инита, забыл закопать мёртвый объект. А с исключением у тебя всегда инвариант "если есть объект, значит можно с ним работать".
                  Ответить
                  • Угу. Даже у нас в джавке это считается некрасивым. Лучше когда все поля финальные, и все устанавливаются в конструкторе. Ну вот я подумал, как это принято делать в С++, и вижу, что так же.
                    Ответить
                    • В крестах все по-разному пишут

                      Можно и через аргумент конструктора код ошибки вернуть, лол 😉
                      Ответить
                      • А потом у тебя объект есть, но пользоваться им нельзя?
                        Удобно!

                        причем деструктор-то у него вызовется!
                        Ответить
                      • А можно сделать конструктор приватным, а объекты создавать только в виде умного указателя статическим методом. Получил пустой указатель - у вас ошибка, разгребайтесь.
                        Ответить
                        • factory method, да)

                          Мы в джавке так делаем, что бы не утёк this, если нужно созданный объект сразу где-то зарегистрировать.
                          Ответить
                        • Для жирных объектов так и делаю, если исключения не завезли. Заодно можно интерфейс вернуть и припрятать реализацию. И даже IoC какой-никакой слепить.
                          Ответить
                          • >жирных
                            А зачем? Чтобы не ебаться с копированием и референсами при передаче? Или чтобы стек не рвать?
                            Ответить
                          • Потому что для жирных объектов насрать на оверхед. А с интерфейсом и юнит-тестик можно хуйнуть и из реализации кишки всякого винапи, позикса и прочего дерьма не торчат.
                            Ответить
                            • Понял.

                              Pointer у тебя на интерфейс IFoo, класс реализован в IFooImp, реализация клиенту не видна. Правда, все методы получаются виртуальные, но всем похуй?
                              Ответить
                            • > Потому что для жирных объектов насрать на оверхед.

                              мы опять про тиндер?
                              Ответить
                    • Предлагаю перейти на "PHP". Нет принуждения к ебучему ООП, можно писать в ясном и понятном процедурном стиле, безо всяких конструкторов, полей, объектов, исключений и остального говна.
                      Ответить
                      • В С++ тоже нет такого принуждения.
                        Да в общем даже в джаве с с# его нет, хотя и рекомендуется
                        Ответить

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

Семь раз отмерь — один отрежь, guest!

    А не использовать ли нам bbcode?


    8