Используете ли вы фигурные скобки для дополнительной проверки?
Я имею в виду не использовать его, когда это требуется для функций, классов, если, while, switch, try-catch.
Я не знал, что это можно сделать, как пока я не увидел этот вопрос SO.
В приведенной выше ссылке Eli упомянул, что "они используют ее для сворачивания своего кода в логических разделах, которые не попадают в функцию, класс, цикл и т.д., которые обычно складываются".
Какие другие виды использования существуют помимо упомянутых?
Хорошо ли использовать фигурные скобки, чтобы ограничить область ваших переменных и расширить область действия только в случае необходимости (работая на основе "необходимости доступа" )? Или это на самом деле глупо?
Как насчет использования областей только для того, чтобы вы могли использовать одни и те же имена переменных в разных областях, но в той же самой большой области? Или лучше повторить использование одной и той же переменной (если вы хотите использовать одно и то же имя переменной) и сохранить при освобождении и распределении (я думаю, некоторые компиляторы могут оптимизировать это?)? Или лучше использовать разные имена переменных?
Ответы
Ответ 1
Если я использую ресурс, который я хочу освободить в определенное время, например:
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...
}
Ответ 2
Я бы не использовал фигурные скобки для этой цели по нескольким причинам.
-
Если ваша конкретная функция достаточно велика, чтобы вам нужно было выполнять различные фокусы, возможно, разбить функцию на более мелкие подфункции.
-
Знакомство с фигурными скобками для повторного использования имен переменных приведет только к путанице и проблемам с кодом.
Только мои 2 цента, но я видел много таких вещей в других материалах лучшей практики.
Ответ 3
Наиболее распространенным "нестандартным" использованием области охвата, которое я использую регулярно, является использование мьютекса с областью.
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
}
Это имеет много преимуществ, но самое главное, что блокировка всегда будет очищена, даже если в защищенном коде выбрано исключение.
Ответ 4
С++
Иногда вам нужно ввести дополнительный уровень привязки для повторного использования имен переменных, когда имеет смысл это сделать:
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;
}
Ответ 5
Наиболее распространенное использование, как говорили другие, заключается в том, чтобы обеспечить, чтобы деструкторы выполнялись, когда вы этого хотите. Это также полезно для того, чтобы сделать код, специфичный для платформы, немного понятным:
#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
Ответ 6
Это может быть благом для генераторов кода. Предположим, у вас есть компилятор Embedded SQL (ESQL); он может захотеть преобразовать инструкцию SQL в блок кода, для которого требуются локальные переменные. Используя блок, он может повторно использовать фиксированные имена переменных снова и снова, вместо того, чтобы создавать все переменные с отдельными именами. Конечно, это не слишком сложно, но это сложнее, чем необходимо.
Ответ 7
Как говорили другие, это довольно распространено в С++ из-за всемогущего RAII (инициализация сбора ресурсов) идиома/шаблон.
Для программистов на Java (и, возможно, С#, я не знаю) это будет иностранная концепция, потому что объекты на основе кучи и GC убивают RAII. IMHO, способный помещать объекты в стек, является самым большим единственным преимуществом С++ над Java и делает хорошо написанный код С++ MUCH более чистым, чем хорошо написанный Java-код.
Ответ 8
Я использую его только тогда, когда мне нужно что-то выпускать с помощью RAII, и даже тогда, когда он должен быть выпущен как можно раньше (например, отключение блокировки).
Ответ 9
Программирование на Java Я довольно часто хотел ограничить область в рамках метода, но мне никогда не приходило в голову использовать ярлык. Поскольку я использую эти ярлыки в качестве объекта разрыва, я использую блок с помеченными надписью с мешем, подобный тому, который вы предположили, именно то, что я хотел в этих случаях.
Часто блоки кода слишком коротки, чтобы вырваться на небольшой метод, и часто код в методе структуры (например, 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) - это функция отладки), но я ненавидел это в несколько мест я попробовал.
Итак, я думаю, что твоя идея хорошая, совсем не глупо. Я всегда думал, что я единственный, кто хотел это сделать.
Ответ 10
Да, я использую эту технику из-за RAII. Я также использую этот метод в простой C, поскольку он приближает переменные. Конечно, я должен думать о том, чтобы разбить функции еще больше.
Одна вещь, которую я делаю, вероятно, стилистически спорна, ставит открытую фигурную фигуру в строке декларации или помещает на нее комментарий. Я хочу уменьшить количество потерянного вертикального пространства. Это основано на рекомендации руководства по стилю Google С++..
/// 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);
}
}
Ответ 11
Я согласен с агартцке. Если вы считаете, что вам нужно сегментировать большие блоки логического кода для удобства чтения, вы должны рассмотреть возможность рефакторинга для очистки занятых и загроможденных членов.
Ответ 12
У него есть свое место, но я не думаю, что это делается так, что $foo может быть здесь одной переменной, а другая переменная там, внутри той же функции или другой (логической, а не лексической) области - хорошая идея, Несмотря на то, что компилятор прекрасно понимает это, кажется, слишком сложно сделать жизнь трудной для людей, пытающихся прочитать код.
Ответ 13
В компании, в которой я работаю, есть политика статического анализа, чтобы поддерживать объявления локальных переменных рядом с началом функции. Много раз использование много строк после первой строки функции, поэтому я не могу сразу увидеть объявление и первую ссылку на экране. То, что я делаю, чтобы "обойти" политику, - это сохранить декларацию рядом с ссылкой, но предоставить дополнительную область, используя фигурные скобки. Однако он увеличивает отступ, и некоторые могут утверждать, что он делает код более уродливым.