Должен ли я использовать спецификатор исключений в C ++?

ИСПОЛЬЗОВАТЬ SIMPHOLDERS

Я использовал это приложение на Xcode 5, открыв папку «Документы» для текущего приложения в симуляторе в Finder.

http: // simpholders.com/

еще не готов к Xcode 6 (начиная с sep 24 2014), но сохраняет все эти проблемы.

В Xcode 6 / iOS8 Теперь пакет отдельно от данных. / GUID приложения регенерируется между прогонами в Xcode (не уверен, почему)

  DOCUMENTS DIR:/Users/gbxc/Library/Developer/CoreSimulator/Devices/AC79941F-EC56-495E-A077-773EEE882732/data/Containers/Data/Application/C220D351-0BE7-46BA-B35E-D16646C61A3F/Documents
mainBundlePath_:/Users/gbxc/Library/Developer/CoreSimulator/Devices/AC79941F-EC56-495E-A077-773EEE882732/data/Containers/Bundle/Application/12200D1D-9B67-408B-BCF7-38206CBE0940/myappname.app/BLANK_BLOG_SCALED.jpg

1. НАЙТИ ПАПКУ УСТРОЙСТВ В СИМУЛЯТОРЕ

/Users/gbxc/Library/Developer/CoreSimulator/Devices/

откройте каждый /device.plist, чтобы узнать, какой GUID - какое устройство в XCode - я думаю, что это статический

3. НАЙДИТЕ УСТРОЙСТВО, на которой вы работаете на iPad 2 - я думаю, что это статический

/Devices/AC79941F-EC56-495E-A077-773EEE882732

4. Найти папку с вашим приложением / документами

/AC79941F-EC56-495E-A077-773EEE882732/data/Containers/Data/Application/C220D351-0BE7-46BA-B35E-D16646C61A3F/Documents

ОЧЕРИТЬ GUID C220D351-0BE7-46BA-B35E-D16646C61A3F регенерируется каждый раз, когда приложение запускается в XCode 6

 NSArray *paths_ = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        if(paths_){
            _docsDir = [paths_ firstObject];
            DebugLog(@"DOCUMENTS DIR:%@",_docsDir);         
        }else{
            ErrorLog(@"paths_ is nil - cant get Documents directory");
        }

MAIN BUNDLE path

NSString *mainBundlePath_ = [[NSBundle mainBundle] pathForResource:@"someimageinyourbundle" ofType:@"jpg"];
/AC79941F-EC56-495E-A077-773EEE882732/data/Containers/Bundle/Application/12200D1D-9B67-408B-BCF7-38206CBE0940/clarksonsiq.app/BLANK_BLOG_SCALED.jpg

НИКОГДА НЕ СКАЧАТЬ ПУТЬ в / Документы между запусками будут меняться.

Я сериализовал его на plist и не мог понять, почему они продолжали исчезать

Указанный GUID / Документы постоянно меняются между прогонами, но если у вас есть / Документы, открытые в Finder, папка остается открытой.

https://devforums.apple.com/thread/235911?tstart=0

https://devforums.apple.com/thread/238754?tstart=0

119
задан iammilind 11 October 2012 в 05:38
поделиться

14 ответов

Нет.

Вот несколько примеров почему:

  1. Код шаблона невозможно записать со спецификациями исключения,

    template<class T>
    void f( T k )
    {
         T x( k );
         x.x();
    }
    

    , копии могли бы бросить, передача параметров могла бы бросить, и x() мог бы выдать некоторое неизвестное исключение.

  2. спецификации Исключения имеют тенденцию запрещать расширяемость.

    virtual void open() throw( FileNotFound );
    

    мог бы развиться в [1 120]

    virtual void open() throw( FileNotFound, SocketNotReady, InterprocessObjectNotImplemented, HardwareUnresponsive );
    

    , Вы могли действительно записать, что как [1 121]

    throw( ... )
    

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

  3. Унаследованный код

    при написании кода, который полагается на другую библиотеку, Вы действительно не знаете то, что это могло бы сделать, когда что-то идет ужасно неправильно.

    int lib_f();
    
    void g() throw( k_too_small_exception )
    { 
       int k = lib_f();
       if( k < 0 ) throw k_too_small_exception();
    }
    

    g завершится, когда lib_f() броски. Это (в большинстве случаев) не, что Вы действительно хотите. std::terminate() никогда не должен называться. Всегда лучше позволить сбою приложения с необработанным исключением, от которого можно получить отслеживание стека, чем тихо/яростно умереть.

  4. Пишут код, который возвращает распространенные ошибки и бросает на исключительные случаи.

    Error e = open( "bla.txt" );
    if( e == FileNotFound )
        MessageUser( "File bla.txt not found" );
    if( e == AccessDenied )
        MessageUser( "Failed to open bla.txt, because we don't have read rights ..." );
    if( e != Success )
        MessageUser( "Failed due to some other error, error code = " + itoa( e ) );
    
    try
    {
       std::vector<TObj> k( 1000 );
       // ...
    }
    catch( const bad_alloc& b )
    { 
       MessageUser( "out of memory, exiting process" );
       throw;
    }
    

, Тем не менее, когда Ваша библиотека просто выдает Ваши собственные исключения, можно использовать спецификации исключения для утверждения намерения.

93
ответ дан Marc Mutz - mmutz 11 October 2012 в 05:38
поделиться

Да, если Вы во внутреннюю документацию. Или возможно при записи libary, который будут использовать другие, так, чтобы они могли сказать то, что происходит, не консультируясь с документацией. Бросок или не бросок можно считать частью API, почти как возвращаемое значение.

я соглашаюсь, они не действительно полезны для осуществления стиля Java правильности в компиляторе, но это - лучше чем ничего или случайные комментарии.

2
ответ дан user10392 11 October 2012 в 05:38
поделиться

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

2
ответ дан Odd 11 October 2012 в 05:38
поделиться

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

Иначе я не нахожу особенно полезным использовать что-либо кроме throw(), чтобы указать, что это не выдает исключений.

3
ответ дан Branan 11 October 2012 в 05:38
поделиться

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

Да, ожидаемое поведение неуказанного исключения, бросаемого от функции со спецификаторами исключения, состоит в том, чтобы назвать оконечным ().

я также отмечу, что Scott Meyers затрагивает эту тему в Более эффективном C++. Его Эффективный C++ и Более эффективный C++ настоятельно рекомендованы книги.

2
ответ дан Kris Kumler 11 October 2012 в 05:38
поделиться

gcc испустит предупреждения при нарушении спецификаций исключения. То, что я делаю, должно использовать макросы для использования спецификаций исключения только в компиляции режима "линта" явно для проверки, чтобы удостовериться, что исключения соглашаются с моей документацией.

8
ответ дан Jeremy 11 October 2012 в 05:38
поделиться

Я думаю стандартно кроме конвенции (для C++)
, спецификаторы Исключения были экспериментом в стандарте C++, который главным образом перестал работать.
исключение, являющееся, что никакой спецификатор броска не полезен, но необходимо также добавить соответствующий блок выгоды попытки внутренне, чтобы удостовериться, что код соответствует спецификатору. У Herb Sutter есть страница на предмете. Gotch 82

В дополнении я думаю, что стоит описать Гарантии Исключения.

Это в основном документация относительно того, как состояние объекта затронуто исключениями, выходящими из метода на том объекте. К сожалению, они не осуществляются или иначе упоминаются компилятором.
Повышение и Исключения

Гарантии Исключения

Никакая Гарантия:

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

Основная Гарантия:

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

Сильная Гарантия: (иначе Транзакционная Гарантия)

Это гарантирует, что метод завершится успешно
, Или Исключение будет выдано, и состояние объектов не изменится.

Никакая Гарантия Броска:

метод гарантирует, что никаким исключениям не позволяют распространить из метода.
Все деструкторы должны сделать эту гарантию.
| N.B. Если исключение выйдет из деструктора, в то время как исключение уже распространяет
|, приложение завершится

14
ответ дан king_nak 11 October 2012 в 05:38
поделиться

Избегайте спецификаций исключения в C++. Причинами, которые Вы приводите в своем вопросе, является довольно хорошее начало для почему.

Посмотрите Herb Sutter "Прагматический Взгляд на Спецификации Исключения" .

42
ответ дан ForceMagic 11 October 2012 в 05:38
поделиться

Единственный полезный спецификатор исключения является "броском ()", поскольку в "не бросает".

7
ответ дан Harold Ekstrom 11 October 2012 в 05:38
поделиться

Нет. Если Вы используете их, и исключение выдается, что Вы не указывали, или Вашим кодом или кодом, названным Вашим кодом, то поведение по умолчанию состоит в том, чтобы быстро завершить Вашу программу.

кроме того, я полагаю, что их использование было удержано от использования в текущих проектах C++ 0x стандарт.

4
ответ дан Ferruccio 11 October 2012 в 05:38
поделиться

Спецификации исключения не являются замечательно полезными инструментами в C++. Однако там/is/хорошее использование для них, если объединено со станд.:: неожиданный.

то, Что я делаю в некоторых проектах, является кодом со спецификациями исключения, и затем назовите set_unexpected () с функцией, которая выдаст специальное исключение моего собственного дизайна. Это исключение, на конструкцию, получает след (определенным для платформы способом) и получено из станд.:: bad_exception (чтобы позволить этому быть распространенным при желании). Если это вызывает оконечное () вызов, как это обычно делает, след печатается тем, что () (а также исходное исключение, которое вызвало его; не к трудно, чтобы найти, что) и таким образом, я получаю информацию того, где мой контракт был нарушен, такой как, какое неожиданное исключение библиотеки было выдано.

, Если я делаю это, я никогда не позволяю распространение исключений библиотеки (кроме станд.) и получаю все мои исключения из станд.:: исключение. Если библиотека решит бросить, то я поймаю и преобразую в свою собственную иерархию, позволяя, чтобы я всегда управлял кодом. Шаблонные функции, которые вызывают зависимые функции, должны избежать спецификаций исключения по очевидным причинам; но редко иметь шаблонный функциональный интерфейс с кодом библиотеки так или иначе (и немного библиотек действительно используют шаблоны полезным способом).

4
ответ дан coppro 11 October 2012 в 05:38
поделиться
  • 1
    Я действительно рассматривал этот метод, но меня просто don' t как идея наличия повторяющегося HTML... – Ben Carey 23 April 2014 в 19:30

Спецификации исключения = мусор, спрашивает любой Java-разработчик старше 30

-1
ответ дан Greg Dean 11 October 2012 в 05:38
поделиться

Из статьи:

http://www.boost.org/community/exception_safety.html

«Хорошо известно, что невозможно написать безопасный для исключений общий контейнер." Это утверждение часто слышно со ссылкой на статью Тома Cargill [4], в котором он исследует проблема исключительной безопасности для общий шаблон стека. В его статьи, Cargill поднимает много полезных вопросы, но, к сожалению, не представить решение его проблемы1. в заключение предполагает, что решение может быть невозможно. К сожалению, его статью прочитали многие как «доказательство» этого предположения. С момента его публикации было много примеров безопасных для исключений общие компоненты, среди которых C ++ стандартные библиотечные контейнеры.

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

0
ответ дан 24 November 2019 в 01:51
поделиться

Спецификация "throw()" позволяет компилятору выполнять некоторые оптимизации при анализе потока кода, если он знает, что функция никогда не выбросит исключение (или, по крайней мере, обещает никогда не выбросить исключение). Ларри Остерман кратко рассказывает об этом здесь:

http://blogs.msdn.com/larryosterman/archive/2006/03/22/558390.aspx

3
ответ дан 24 November 2019 в 01:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: