Вы используете фигурные скобки для дополнительного определения объема? [закрытый]


Я имею в виду, кроме использования его, когда это требуется для функций, классов, if, while, switch, try-catch.

Я не знал, что это можно сделать, как это, пока я не увидел этот так Вопрос.

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

Какие еще существуют применения, кроме упомянутых?

Хорошо ли использовать фигурные фигурные скобки, чтобы ограничить область ваших переменных и расширить область только в случае необходимости (работая на основе" need-to-access")? Или это действительно глупо?

Как насчет использования областей просто так, чтобы вы могли использовать одни и те же имена переменных в разных областях, но в одной и той же большей области? Или лучше использовать одну и ту же переменную повторно (если вы хотите использовать одно и то же имя переменной) и сэкономить на освобождении и выделении (я думаю, некоторые компиляторы могут оптимизировать на этом?)? Или лучше использовать разные имена переменных вообще?

13 36

13 ответов:

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

void myfunction()
{
  {
  // Open serial port
     SerialPort port("COM1", 9600);
     port.doTransfer(data);
  } // Serial port gets closed here.

  for(int i = 0; i < data.size(); i++)
     doProcessData(data[i]);
  etc...
}

Я бы не стал использовать фигурные скобки для этой цели по нескольким причинам.

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

  2. Введение фигурных скобок для определения области для повторного использования имен переменных только приведет к путанице и проблемам в коде.

Только мои 2 цента, но я видел много таких вещей в других материалах лучшей практики.

Наиболее распространенное "нестандартное" использование области видимости, которое я использую регулярно,-это использование мьютекса с областью видимости.

void MyClass::Somefun()
{
    //do some stuff
    {
        // example imlementation that has a mutex passed into a lock object:
        scopedMutex lockObject(m_mutex); 

        // protected code here

    } // mutex is unlocked here
    // more code here
}
Это имеет много преимуществ, но самым важным является то, что блокировка всегда будет очищена, даже если в защищенном коде возникнет исключение.

С++:

Иногда требуется ввести дополнительный уровень скобок области для повторного использования имен переменных, когда это имеет смысл сделать:

switch (x) {
    case 0:
        int i = 0;
        foo(i);
        break;
    case 1:
        int i = 1;
        bar(i);
        break;
}

Приведенный выше код не компилируется. Вам нужно сделать это:

switch (x) {
    case 0:
        {
            int i = 0;
            foo(i);
        }
        break;
    case 1:
        {
            int i = 1;
            bar(i);
        }
        break;
}

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

#if defined( UNIX )
    if( some unix-specific condition )
#endif
    {
        // This code should always run on Windows but 
        // only if the above condition holds on unix
    }

Код, построенный для Windows, не видит if, только фигурные скобки. Это гораздо яснее, чем:

#if defined( UNIX )
    if( some unix-specific condition ) {
#endif
        // This code should always run on Windows but 
        // only if the above condition holds on unix
#if defined( UNIX )
    }
#endif

Это может быть благом для генераторов кода. Предположим, у вас есть встроенный компилятор SQL (ESQL); он может захотеть преобразовать инструкцию SQL в блок кода, которому нужны локальные переменные. Используя блок, он может повторно использовать имена фиксированных переменных снова и снова, вместо того, чтобы создавать все переменные с отдельными именами. Конечно, это не слишком трудно, но все же труднее, чем необходимо.

Как уже говорили другие, это довольно распространено в C++ из-за всемогущей идиомы RAII (Resource acquisition is initialization)/pattern.

Для Java-программистов (и, возможно, C#, я не знаю) это будет чужеродная концепция, потому что объекты на основе кучи и GC убивают RAII. ИМХО, возможность помещать объекты в стек является самым большим преимуществом C++ по сравнению с Java и делает хорошо написанный код C++ намного чище, чем хорошо написанный код Java.

Я использую его только тогда, когда мне нужно освободить что-то с помощью RAII, и даже тогда, когда это должно быть освобождено как можно раньше (например, освобождение блокировки).

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

Часто блоки кода слишком коротки, чтобы разбиться на небольшой метод, и часто код в методе фреймворка (например, startup () или shutdown ()), и на самом деле лучше сохранить код вместе в одном методе.

Лично я ненавижу простые плавающие / висячие скобки (хотя это потому, что мы являемся строгим магазином отступов в стиле баннеров), и я ненавижу маркер комментария:

// yuk!
some code
{
scoped code
}
more code

// also yuk!
some code
/* do xyz */ {
    scoped code
    }
some more code

// this I like
some code
DoXyz: {
    scoped code
    }
some more code

Мы рассматривали использование "if (true) {" , потому что спецификация Java специально говорит, что они будут оптимизированы в компиляции (как и все содержимое if (false) - это функция отладки), но я ненавидел это в тех немногих местах, где я попробовал его.

Так что я думаю, что ваша идея хороша, не на все это глупо. Я всегда думал, что я был единственным, кто хотел сделать это.

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

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

/// c++ code
/// references to boost::test
BOOST_TEST_CASE( curly_brace )
{
  // init
  MyClass instance_to_test( "initial", TestCase::STUFF ); {
    instance_to_test.permutate(42u);
    instance_to_test.rotate_left_face();
    instance_to_test.top_gun();
  }
  { // test check
    const uint8_t kEXP_FAP_BOOST = 240u;
    BOOST_CHECK_EQUAL( instance_to_test.get_fap_boost(), kEXP_FAP_BOOST);
  }
}

Я согласен с agartzke. Если вы чувствуете, что вам нужно сегментировать большие логические блоки кода для удобства чтения, вы должны рассмотреть возможность рефакторинга, чтобы очистить занятые и загроможденные элементы.

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

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