Существует ли привилегированная идиома для подражания попытке/наконец Java в C++?

Если вы доверяете источнику данных, вы можете использовать eval для преобразования вашей строки в словарь:

eval(your_json_format_string)

Пример:

>>> x = "{'a' : 1, 'b' : True, 'c' : 'C'}"
>>> y = eval(x)

>>> print x
{'a' : 1, 'b' : True, 'c' : 'C'}
>>> print y
{'a': 1, 'c': 'C', 'b': True}

>>> print type(x), type(y)
<type 'str'> <type 'dict'>

>>> print y['a'], type(y['a'])
1 <type 'int'>

>>> print y['a'], type(y['b'])
1 <type 'bool'>

>>> print y['a'], type(y['c'])
1 <type 'str'>
13
задан RogerV 2 February 2009 в 15:12
поделиться

14 ответов

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

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

ОБНОВЛЕНИЕ : Прямо из первых уст: , Почему C++ не обеспечивает "наконец" конструкция?

26
ответ дан 1 December 2019 в 17:11
поделиться

Мысль я добавил бы свое собственное решение этого - своего рода обертка интеллектуального указателя для того, когда необходимо иметь дело с типами non-RAII.

Используемый как это:

Finaliser< IMAPITable, Releaser > contentsTable;
// now contentsTable can be used as if it were of type IMAPITable*,
// but will be automatically released when it goes out of scope.

, Таким образом, вот реализация Финализатора:

/*  Finaliser
    Wrap an object and run some action on it when it runs out of scope.
    (A kind of 'finally.')
    * T: type of wrapped object.
    * R: type of a 'releaser' (class providing static void release( T* object )). */
template< class T, class R >
class Finaliser
{
private:
    T* object_;

public:
    explicit Finaliser( T* object = NULL )
    {
        object_ = object;
    }

    ~Finaliser() throw()
    {
        release();
    }

    Finaliser< T, R >& operator=( T* object )
    {
        if (object_ != object && object_ != NULL)
        {
            release();
        }
        object_ = object;

        return *this;
    }

    T* operator->() const
    {
        return object_;
    }

    T** operator&()
    {
        return &object_;
    }

    operator T*()
    {
        return object_;
    }

private:
    void release() throw()
    {
        R::release< T >( object_ );
    }
};

... и вот Releaser:

/*  Releaser
    Calls Release() on the object (for use with Finaliser). */
class Releaser
{
public:
    template< class T > static void release( T* object )
    {
        if (object != NULL)
        {
            object->Release();
        }
    }
};

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

0
ответ дан 1 December 2019 в 17:11
поделиться

Относительно Вашего редактирования приложения, да закрывают, рассматриваются для C++ 0x. Они могут использоваться с ограниченной по объему защитой RAII, чтобы предоставить простое в использовании решение, проверить блог Pizer. Они могут также использоваться, чтобы подражать попытке наконец, видеть этот ответ ; но это действительно хорошая идея? .

0
ответ дан 1 December 2019 в 17:11
поделиться

Я сделал много дизайна класса и обрабатываю дизайн обертки по шаблону в C++ за те 15 лет и сделанный все это C++ путь с точки зрения чистки деструкторов. Каждый проект, тем не менее, также неизменно включил использование библиотек C, которые предоставили ресурсам открытое это, используйте его, закройте его модель использования. Попытка/наконец означала бы, что такой ресурс может просто быть использован, где это должно быть - абсолютно устойчивым способом - и быть сделано с ним. Наименьшее количество подхода скуки к программированию той ситуации. Мог иметь дело со всеми другими состояние, продолжающееся во время логики той очистки, не имея необходимость быть ограниченным по объему далеко в некотором деструкторе обертки.

я сделал большую часть своего кодирования C++ в Windows, так мог всегда обращаться к использованию Microsoft __ попытка / __ наконец для таких ситуаций. (Их структурированная обработка исключений имеет некоторые мощные способности к взаимодействию за исключениями.) Увы, не похож на язык C, когда-либо ратифицировал любые портативные конструкции обработки исключений.

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

0
ответ дан 1 December 2019 в 17:11
поделиться

Не completetely offtopic.

Бойлер, Обшивающий Очистку Ресурса DB металлическим листом в режиме Java

сарказма: разве идиома Java не замечательна?

1
ответ дан 1 December 2019 в 17:11
поделиться

Я думаю, что Вы упускаете суть того, что catch (...) может сделать.

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

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

catch (...) не часто полезно в C++. Это может использоваться в местах, которые должны гарантировать, что они не бросают или только выдают определенные законтрактованные исключения. Если Вы используете catch (...) для очистки затем существует очень хороший шанс, что Ваш код не является надежно исключением, безопасным в любом случае.

, Как упомянуто в других ответах при использовании локальных объектов для управления ресурсами (RAII) затем, он может удивлять и просвещать, как немного блоков выгоды, в которых Вы нуждаетесь, часто - если Вы ничего не должны делать локально за исключением - даже блок попытки, могут быть избыточными, поскольку Вы позволяете исключениям вытечь к клиентскому коду, который может ответить на них, все еще гарантирование никакого ресурса выходит.

Для ответа на исходный вопрос при необходимости в некоторой части кода для выполнения в конце блока, исключения или никакого исключения, затем рецепт был бы.

class LocalFinallyReplacement {
    ~LocalFinallyReplacement() { /* Finally code goes here */ }
};
// ...
{ // some function...
    LocalFinallyReplacement lfr; // must be a named object

    // do something
}

Примечание, как мы можем полностью покончить try, catch и throw.

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

1
ответ дан 1 December 2019 в 17:11
поделиться

Деструкторы C++ делают finally избыточный. Можно получить тот же эффект путем перемещения кода очистки от наконец до соответствующих деструкторов.

1
ответ дан 1 December 2019 в 17:11
поделиться

Чтобы избежать необходимости определять класс обертки для каждого публикуемого ресурса, можно интересоваться ScopeGuard ( http://www.ddj.com/cpp/184403758 ), который позволяет создавать "инструменты для очистки" на лету.

, Например:

FILE* fp = SomeExternalFunction();
// Will automatically call fclose(fp) when going out of scope
ScopeGuard file_guard = MakeGuard(fclose, fp);
4
ответ дан 1 December 2019 в 17:11
поделиться

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

попытка... наконец создает, платформа для функций очистки. Это - поощренный к языку способ написать паршивый код. Кроме того, так как это поощряет писать тот же код очистки много раз, это подрывает принцип DRY.

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

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

существует много проблем с C++, но это не один из них. Существуют пути, которыми Java лучше, чем C++, но это не один из них.

Java был бы очень более обеспечен со способом реализовать RAII вместо попытки... наконец.

5
ответ дан 1 December 2019 в 17:11
поделиться

Хорошо, я должен добавить в ответе на точки, которые Вы сделали в отдельном сообщении ответа: (Было бы намного более удобно при редактировании этого в исходный вопрос таким образом, это не заканчивается внизу ниже ответы на него.

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

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

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

Действительно? Если мы хотим это к всегда , происходят для этого типа (скажите, мы всегда хотим закрыть соединение с базой данных, когда мы сделаны с ним), то, почему мы не определяем его однажды ? В самом типе? Сделайте соединение с базой данных близко само, вместо того, чтобы иметь необходимость поместить попытку/наконец вокруг каждого использования его?

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

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

программисты на C++ No. никогда не заполонялись этим. C программисты имеют. И программисты C, которые поняли, что C++ имел классы и затем назвал себя программистами на C++, имеют.

я программирую в C++ и C# ежедневно, и я чувствую, что заполоняюсь смешной настойчивостью C#, которую я должен предоставить наконец пункт (или using блок) КАЖДЫЙ РАЗ, когда я использую соединение с базой данных или что-то еще, что должно быть очищено.

C++ позволяет мне указать раз и навсегда, что "каждый раз, когда мы сделаны с этим типом, он должен выполнить эти действия". Я не рискую забывать освобождать память. Я не рискую забывать закрывать дескрипторы файлов, сокеты или соединения с базой данных. Поскольку моя память, мои дескрипторы, сокеты и соединения дб делают это сами.

, Как может он когда-нибудь быть предпочтительным должными быть написать дублирующийся код очистки каждый раз, Вы используете тип? Если необходимо перенести тип, потому что он не имеет самого деструктора, у Вас есть две легких опции:

  • Ищут надлежащую библиотеку C++, которая обеспечивает этот деструктор (подсказка: Повышение)
  • повышение Использования:: shared_ptr, чтобы перенести его и предоставить его пользовательский функтор во времени выполнения, указывая очистку, которая будет сделана.

, Когда Вы пишете программное обеспечение сервера приложений как Java серверы приложений EE Glassfish, JBoss, и т.д., Вы хотите смочь поймать и зарегистрировать информацию об исключении - в противоположность позволенному, это падает на пол. Или худшее падение во время выполнения и причину неизящный резкий выход сервера приложений. Вот почему очень желательно иметь всеобъемлющий базовый класс для любого возможного исключения. И C++ имеет просто такой класс. станд.:: исключение.

сделали C++ со дней CFront и Java/C# большая часть этого десятилетия. Ясно видеть, что существует только огромный разрыв культуры в том, как приближаются к существенно подобным вещам.

нет, Вы никогда не делали C++. Вы сделали CFront или C с классами. Не C++. Существует огромная разница. Выход называя ответы Ламе, и Вы могли бы узнать что-то о языке, Вы думали, что знали. ;)

9
ответ дан 1 December 2019 в 17:11
поделиться

Нет наконец не был добавлен к C++, и при этом он, вероятно, никогда не будет добавляться.

способ, которым C++ использует конструктора/деструктор, делает потребность в наконец ненужном.
при использовании выгоды (...) для очистки затем, Вы не используете C++ правильно. Код очистки должен все быть в деструкторе.

, Хотя это не требование для использования его, C++ действительно имеет станд.:: исключение.
разработчики Принуждения для получения из определенного класса для использования исключения идет вразрез с содержанием это простая философия C++. Также, почему мы не требуем, чтобы все классы произошли из Объекта.

Read: Делает поддержку C++ ' finally' блоки? (И what' s этот ' RAII' я продолжаю слышать о?)

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

10
ответ дан 1 December 2019 в 17:11
поделиться

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

Read http://en.wikipedia.org/wiki/Resource_acquisition_is_initialization

11
ответ дан 1 December 2019 в 17:11
поделиться

Мои.02$. Я программировал на управляемых языках как C# и Java в течение многих лет, но был вынужден переключиться на C++ в целях скорости. Сначала я не мог верить, как я должен был выписать сигнатуру метода дважды в заголовочном файле и затем cpp файле, и мне не нравилось, как был не наконец блок, и никакая сборка "мусора" не означала отслеживать утечки памяти везде - черт возьми мне не нравился он вообще!

Однако, поскольку я сказал, что был вынужден использовать C++. Таким образом, я был вынужден серьезно изучить это, и теперь я наконец понял все идиомы программирования как RAII, и я получаю всю тонкость языка и такого. Это взяло меня некоторое время, но теперь я вижу, как отличающийся из языка это сравнивается с C# или Java.

В эти дни я думаю, что C++ является лучшим языком существует! Да, я могу понять, что существует немного больше, что я иногда называю 'дипольной помехой' (на вид ненужный материал для записи), но после фактического использования языка серьезно, я передумал об этом полностью.

я раньше имел утечки памяти все время. Я раньше писал весь мой код в.h файл, потому что я ненавидел разделение кода, я не мог понять, почему они сделают это! И я раньше всегда заканчивал с циклическим глупым, включают зависимости и "кучу" больше. Я был действительно одержим C# или Java мне, C++ был огромным шагом вниз. В эти дни я получаю его. У меня почти никогда нет утечек памяти, я наслаждаюсь разделением интерфейса и реализацией, и у меня нет проблем с зависимостями от цикла больше.

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

С уважением, что я думаю, продолжается, Вы просто привыкли к Java теперь, точно так же, как я был.

15
ответ дан 1 December 2019 в 17:11
поделиться

Пример того, как трудный это должно использовать наконец правильно.

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

В C++

void foo()
{
    std::ifstream    data("plop");
    std::ofstream    output("plep");

    // DO STUFF
    // Files closed auto-magically
}

На языке без деструкторов, но имеет наконец пункт.

void foo()
{
    File            data("plop");
    File            output("plep");

    try
    {
        // DO STUFF
    }
    finally
    {
        // Must guarantee that both files are closed.
        try {data.close();}  catch(Throwable e){/*Ignore*/}
        try {output.close();}catch(Throwable e){/*Ignore*/}
    }
}

Это - простой пример, и уже код становится замысловатым. Здесь мы только пытаемся упорядочить 2 простых ресурса. Но поскольку количество ресурсов, которыми нужно управлять увеличения и/или их сложность, увеличивает использование наконец, блок становится более твердым и более твердым использовать правильно в присутствии исключений.

использование наконец перемещает ответственность за корректное использование на пользователя объекта. При помощи механизма конструктора/деструктора, обеспеченного C++, Вы перемещаете ответственность корректного использования разработчику/реализатору класса. Это inheritanly более безопасный, поскольку разработчик только должен сделать это правильно однажды на уровне класса (а не сделайте, чтобы различные пользователи попытались сделать это правильно по-разному).

3
ответ дан 1 December 2019 в 17:11
поделиться
Другие вопросы по тегам:

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