你用花括号来做额外的范围吗?
我的意思是除了使用它时所需的function,类,如果,而切换,尝试赶上。
我不知道可以这样做, 直到我看到这个问题 。
在上面的链接中,Eli提到:“他们用逻辑部分来折叠代码,这些逻辑部分不属于通常会被折叠的函数,类,循环等等。
除了那些提到的还有什么其他用途?
使用大括号来限制variables的作用域,并且只在需要的时候扩展作用域(在“需要访问”的基础上工作)是不是一个好主意? 或者它实际上是愚蠢的?
如何使用范围,以便您可以在不同的范围使用相同的variables名称,但在相同的更大范围内? 或者是一个更好的做法是重用相同的variables(如果你想使用相同的variables名),并节省取消分配和分配(我认为一些编译器可以优化呢?)? 或者更好地使用不同的variables名称?
如果我正在使用我想在特定时间释放的资源,例如:
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... }
出于几个原因,我不会为此使用花括号。
-
如果你的特定function足够大,你需要做各种范围的技巧,可能会把function分解成更小的子function。
-
引入用于确定范围以重用variables名称的大括号只会导致代码中的混淆和麻烦。
只是我的2分钱,但是我在其他最佳实践材料中看到了很多这些types的东西。
我经常使用的范围最常见的“非标准”使用是使用范围的互斥体。
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 }
这有很多好处,但最重要的是,即使在受保护的代码中抛出exception,锁也总是被清理干净。
C ++ :
有时你需要引入一个额外的支持级别的范围来重用variables名称,这是有道理的:
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构build的代码没有看到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
代码生成器可以是一个福音。 假设你有一个embedded式SQL(ESQL)编译器; 它可能希望将SQL语句转换为需要本地variables的代码块。 通过使用块,它可以重复使用固定variables名称,而不必使用单独的名称创build所有variables。 当然,这不是太难,但是比必要的更难。
正如其他人所说,由于全能的RAII(资源获取是初始化)成语/模式,在C ++中这是相当普遍的。
对于Java程序员(也许C#,我不知道),这将是一个外国的概念,因为基于堆的对象和GC杀死RAII。 恕我直言,能够在堆栈上放置对象是C ++相对于Java的最大单一优势,并且使编写良好的C ++代码比编写良好的Java代码更清晰。
我只是在我需要用RAII的方式释放某些东西的时候才使用它,甚至只有当我尽可能早地释放它的时候(例如释放一个锁)。
用Java编程我经常想要限制一个方法的范围,但是我从来没有想过使用一个标签。 因为我用大写的时候把标签当作rest的目标,所以使用像你所build议的混合大小写标签的块就是我在这种场合所要求的。
通常情况下,代码块太短而不能分解成小的方法,而且通常是框架方法(如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)的全部内容也是一个debuggingfunction),但是我讨厌在less数地方我尝试过这个。
所以我觉得你的想法很好,一点也不傻。 我一直以为我是唯一一个想要这样做的人。
是的,我使用这种技术是因为RAII。 我也在C中使用这种技术,因为它将variables放在一起。 当然,我应该考虑进一步分解这些function。
我所做的一件事可能是风格上有争议的,就是把宣言中的大括号放在宣言的正文上,或者就此发表评论。 我想减less浪费的垂直空间的数量。 这是基于Google C ++风格指南的build议。 。
/// 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可以是一个variables,而在这个variables中 ,在同一个函数或其他(逻辑的,而不是词法的)范围内的variables是一个好主意。 即使编译器可以完美地理解,看起来很可能使人们试图阅读代码变得困难。
我正在工作的公司有一个静态分析政策,以保持本地variables声明靠近函数的开始。 很多时候,函数的第一行之后的用法是多行,所以我不能同时在屏幕上看到声明和第一个引用。 我所做的“规避”政策是将声明保留在参考文献的附近,但使用大括号提供额外的范围。 它虽然增加了缩进,有些人可能会认为它使代码更丑。