Тут размещают свои топики новички в С/С++.

Тема в разделе "LANGS.C", создана пользователем nitrotoluol, 4 мар 2007.

  1. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    MirrorBlack
    при включенной оптимизации естественно компилятор удаляет всё лишнее, в том числе и неиспользуемые в дальнейшем присвоения. Либо используй потом rectWnd.top, либо отключи оптимизацию.
    С глобальной работает потому что компилятор предполагет, что её может использовать какая-то другая подпрограмма, а здесь бессмысленность очевидна ;)
     
  2. MirrorBlack

    MirrorBlack Алексей

    Публикаций:
    0
    Регистрация:
    21 июн 2008
    Сообщения:
    249
    Адрес:
    Moscow
    Y_Mur
    Вразумил :)
     
  3. dotzen

    dotzen New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2008
    Сообщения:
    10
    Вопрос:
    Как выделить правильно паметь вот для такой "матрицы"? ...

    1.123540
    2.1240
    3.160
    4.50
    5.230
    6.0

    Я могу выделить к примеру матрицу 6х6 и хранить подобную матрицу в ней, но всёже любопытно если это возможно.
     
  4. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    dotzen
    Тут скорее не "правильно", а "на что фантазии хватит". :) Обычно выделяется память под массив указателей. После этого выделяется память для каждого массива (или для всех вместе), а указатели на каждый массив записываются в первый массив указателей.
     
  5. MirrorBlack

    MirrorBlack Алексей

    Публикаций:
    0
    Регистрация:
    21 июн 2008
    Сообщения:
    249
    Адрес:
    Moscow
    Не могу разобраться с конструктором/деструктором.
    Например в конструкторе я выделяю память. Выделение заканчивается ошибкой.
    Так собственно вопрос - как об этом безобразии узнать?
    Напрашивается вариант: переменная в объекте показывающая статус выполнения конструктора.
    И нормально ли то, что можно вызывать деструктор много раз?
     
  6. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    MirrorBlack
    Для этого безобразия можно воспользоваться исключениями. Но по-нормальному лучше сделать отдельный метод инициализации, например - Init. Проблема в том, что конструкторы могут вызываться неявно, и тогда будет жо..

    Нормально никогда самим не вызывать деструктор, а уничтожать объект оператором delete.
     
  7. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    MirrorBlack

    Если operator new не смог выделить память, то поведением по умолчанию будет генерация исключения std::bad_alloc. Если же используются иные методы выделения памяти (malloc/HeapAlloc/и т.д.), то такие ситуации нужно хендлить руками, т.к. си-подобное апи исключений не кидает.


    Booster

    Это bad style. Конструктор он на то и конструктор, чтобы инициализировать объект. C++ это не Delphi с его повсеместным Init/Run/Done. Для того чтобы не было проблем с неявными преобразованиями нужно использовать explicit конструкторы. По некоторым причинам нужно быть поаккуратнее с исключениями в конструкторах копирования. Исключения в остальных конструкторах - абсолютно безобидная ситуация, ничем не хуже исключения в обычной функции (той же Init). Вынос инициализации в отдельную функцию имеет смысл только в некоторых экзотических случаях, к коим обычные исключения в конструкторах, конечно же, не относятся. Таким случаем может быть например виртуальная функция init как отложенная инициализация объекта, если объект например является некоторым состоянием и создается когда еще живо предыдущее состояние, но должен быть проинициализирован только после удаления предыдущего состояния. Создание нового состояния - удаление старого - инициализация нового. В некоторых случаях это необходимо. Но опять же, исключения тут не при чем.

    Здесь же речь же идет о std::bad_alloc. Исключение, генерируемое из-за нехватки памяти, это особое исключение, т.к. его возникновение говорит о том, что у программы меньше всего шансов остаться работоспособной и не грохнуться по сравнению с любым другим исключением. Об этом когда-то давно говорил еще Саттер. О том, как вести себя при исключении в конструкторах и как вести себя вообще при std::bad_alloc нужно думать отдельно - это две очень разные ситуации с очень разными возможными последствиями.
     
  8. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    _DEN_
    Тут уже надо выбирать или гибкость и удобство или слепое следование принципам ООП с гемороем. Хотя конечно пример с выделением памяти не очень показателен, но всё же. И дело тут не совсем в explicit, а в том что предугадать кол-во временных объектов не всегда возможно. Например когда мы из функции возвращаем объект, то разные компиляторы с разными опциями делают это по-разному, в том числе с кучей временных объектов.
    Потом не все и не всегда декларируют исключения, и оказывается что у клиента программа падает, а мы и не знали, что конструктор может генерировать исключение. По-этому отдельный метод инициализации, который в отличие от конструктора имеет возможность возвращать значение, по-моему очень актуален. Неплохо было-бы вспомнить зачем вообще были придуманы исключения.
    Про отложенную инициализацию ты уже сказал, тут мне добавить нечего, кроме того что это очень полезная штука.
     
  9. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Booster

    Во-первых, я не совсем понял, где там у меня "слепое следование принципам ООП с гемороем". Во-вторых, C++ - не объектно-ориентированный язык, а мультипарадигменный. То есть ООП - лишь одна из возможных парадигм в C++. В третьих, исключения как способ error handling-а не имеют никакого отношения к ООП.


    Да, неплохо бы :derisive: Исключение говорит (должно говорить) о нарушении инварианта, в то время как возвращаемое значение говорит о ветвлении логики без нарушения инвариантов. Мне трудно себе представить такую отложенную инициализацию, в которой следовало бы использовать возвращаемое значение, а не исключение. То есть представить-то можно, только это скорее будет убер-экзотический случай. В 99% ошибка инициализации есть нарушение инварианта, то есть должно кидаться исключение.

    В тех редких случаях когда ошибка создания объекта не является нарушением инвариантов обычно делают фри-функцию для создания, а не мембер-функцию для инициализации.

    Код (Text):
    1. typedef boost::shared_ptr<file> file_ptr;
    2.  
    3. file_ptr fp = file::create("c:/1.txt");
    4.  
    5. if(fp)
    6. {
    7.     ...
    8. }
    9. else
    10. {
    11.     ...
    12. }
     
  10. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    _DEN_
    Всё это очень здорово, но ты снова подходишь с теоретических позиций. На практике же всё несколько иначе. Я уже писал про некоторые грабли, на которые я самолично натыкался на практике. Например когда создатель библиотеки забыл, что один из его объектов может генерить исключение в конструкторе. А нас предупредили, что за такие вещи будут карать нещадно, вплоть до увольнения. Или тот же вектор, подумаешь что он там копирует объекты направо и налево, и что у нас объекты будут постоянно блокировать ресурсы и гонять огромное кол-во памяти.

    Если ты про фабрику, то это всё равно совмещение создания объекта и его инициализации, что не всегда приемлемо. Это можно сделать, но если объект работает с нетривиальными ресурсами, то у пользователя класса должна быть возможность разделения фаз.

    Инициализация сама по себе атомарна. Аргументировать применения исключений инвариантом несколько странно. Почему нельзя использовать возвращаемое значение? ОПП мышление не позволяет? Исключения более сложны в обработке, загромождают код - try, catch. И вообще это по большей части костыль.
     
  11. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Booster

    После такого феерического заявления я просто не знаю о чем тут дальше можно разговаривать. Удачи.
     
  12. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    Booster
    да _DEN_ прав, на счёт ексептов, Вы немного погорячились :)
     
  13. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    _DEN_
    Ваше право. Я не отвергаю исключений, они бывают полезны. Но не надо их всюду тыкать. Исключения и есть костыль, придуманные чтобы генерировать ошибку там где нельзя вернуть статус.

    wsd
    В чём я погорячился? Я написал, что без них часто вполне можно обойтись. И там где вместо генерации эксепшена можно вернуть статус, я так и сделаю.
     
  14. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    Booster
    это смотря как смотреть на причину самой ситуации, приводящей к "неудаче". следовательно, и вести себя следует __соответствующе__ адекватно.

    и потом,
    возвращать статус - это, по-идее, си-стайл.
     
  15. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    Booster
    в том что перед такими суждениями стоит ставить ИМХО
    не раз же ты наверное смотрел сырцы опенсорс С++ проектов? так обрати внимание что они
    по основной массе ексепто-ориентированные.
    и как-бы здесь не развязалась религиозная война на счёт статусов против ексептов.. :dntknw:
     
  16. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Предпочитаете исключения статусам?

    Если что-то нехило поднимет производительность, я не буду слепо следовать постулатам.

    Конечно, адекватность прежде всего. Но на практике обычно с исключениями такая каша. Ничего толком правильно не обрабатывается, а ставится catch(...), и если мы в него попадаем, то приложение просто закрывается.

    Кто-то тут говорил, что опенсорс это полное фуфло. ^)
     
  17. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    Booster
    Дениска?
     
  18. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    wsd
    Угу.

    Не ну реально, по-моему не очень хорошая мысль в конструктор без параметров пихать работу с нетривиальными ресурсами. А эксепшен или нет, это уже тонкости реализации конкретной цели.
     
  19. RedLord

    RedLord Member

    Публикаций:
    0
    Регистрация:
    23 июн 2005
    Сообщения:
    183
    Адрес:
    Ukraine
    Booster
    а что представляет объект между созданием и инициализацией? в каком он состоянии находится? и что будет, если я попытаюсь работать с ним до вызова некоего Init?
     
  20. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Ну будет не до конца проинициализированный объект, и что с того, глаза мозолит? Работают например с fstream и ничего, зато удобно. Зачем мне сразу открывать файл, если возможно это никогда не понадобится? По-моему как минимум надо дать пользователю возможность разделения фаз. Зачем ограничивать область применения?

    И насчёт исключений. Всё здорово в кабинетной тиши, в теории, но когда доходит до дела, то мама не горюй. Когда в проекте завязаны десятки и сотни людей, когда каждый делает как хочет, и документации практически никакой. Возвращаемые значения проще обработать, меньше вероятность ошибиться, а в сложных и ответственных клиент-серверных приложениях это очень немаловажно. Я работал в такой кампании и там исключения были запрещены, и наверно не случайно. Ну а опенсорс, это отдельная песня, не зря наверно серьёзные компании их принципиально не используют.