C++ C+中的额外支架+;代码

C++ C+中的额外支架+;代码,c++,curly-braces,C++,Curly Braces,有时您会遇到一些代码,这些代码有额外的大括号,与范围无关,只是为了可读性和避免错误 例如: GetMutexLock( handle ) ; { // brace brackets "scope" the lock, // must close block / remember // to release the handle. // similar to C#'s lock construct } ReleaseMutexLock( handle ) ; 我见过的其他地方有

有时您会遇到一些代码,这些代码有额外的大括号,与范围无关,只是为了可读性和避免错误

例如:

GetMutexLock( handle ) ; 
{
  // brace brackets "scope" the lock,
  // must close block / remember
  // to release the handle.
  // similar to C#'s lock construct
}
ReleaseMutexLock( handle ) ;
我见过的其他地方有:

glBegin( GL_TRIANGLES ) ;
{
  glVertex3d( .. ) ;
  glVertex3d( .. ) ;
  glVertex3d( .. ) ;
} // must remember to glEnd!
glEnd() ; 
如果未释放互斥锁(假设您同时记住了}和
Release()
调用),则会导致编译器错误

  • 这种做法不好吗?为什么?
  • 如果它不是一个,它会改变代码的编译方式还是让它变慢

  • 这是个不错的练习。它不会使任何东西变慢;这只是构建代码的一种方式


    让编译器为您执行错误检查和强制执行总是一件好事

    任何提高可读性的方法都是好的实践。若添加大括号有助于提高可读性,那个就去做吧


    添加其他大括号不会改变代码的编译方式。它不会使程序运行变慢。

    大括号会影响变量范围。据我所知,这就是他们所做的一切

    是的,这会影响程序的编译方式。析构函数将在块的末尾调用,而不是等到函数的末尾

    通常这就是你想要做的。例如,您的GETMutExCube和ReleaseMutexLock将是更好的C++代码,编写如下:

    struct MutexLocker {
      Handle handle;
      MutexLocker(handle) : handle(handle) { GetMutexLock(handle); }
      ~MutexLocker() { ReleaseMutexLock(handle); }    
    };
    ...
    {
      MutexLocker lock(handle);
      // brace brackets "scope" the lock,
      // must close block / remember
      // to release the handle.
      // similar to C#'s lock construct
    }
    

    使用更多的C++样式,锁在块的末尾自动释放。它将在所有情况下发布,包括异常,setjmp/longjmp或程序崩溃或中止除外。

    大括号本身很好,它们所做的只是限制范围,不会减慢任何速度。它可以被视为更干净。(总是喜欢干净的代码而不是快速的代码,如果它更干净的话,在评测之前不要担心速度。)


    但是对于资源来说,这是一种不好的做法,因为你把自己置于一个泄露资源的位置。如果街区里有任何东西抛出或返回,砰,你就死定了

    使用范围绑定资源管理(SBRM,也称为RAII),通过使用析构函数将资源限制在一个范围内:

    class mutex_lock
    {
    public:
        mutex_lock(HANDLE pHandle) :
        mHandle(pHandle)
        {
            //acquire resource
            GetMutexLock(mHandle);
        }
    
        ~mutex_lock()
        {
            // release resource, bound to scope
            ReleaseMutexLock(mHandle);
        }
    
    private:
        // resource
        HANDLE mHandle;
    
        // noncopyable
        mutex_lock(const mutex_lock&);
        mutex_lock& operator=(const mutex_lock&);
    };
    
    所以你得到:

    {
      mutex_lock m(handle);
      // brace brackets "scope" the lock,
      // AUTOMATICALLY
    }
    

    这样做将节省所有资源,更清洁、更安全。如果你能说“我需要释放这个资源”,那你就错了;它们应该被自动处理。

    除非编译器完全疯了,否则除了在该块的末尾而不是周围块的末尾调用任何析构函数外,对编译后的代码没有任何影响

    就我个人而言,我会称之为坏习惯;避免您在这里可能犯的错误的方法是使用范围资源管理(有时称为RAII),而不是使用容易出错的打印提醒。我会像这样写代码

    {
        mutex::scoped_lock lock(mutex);
        // brace brackets *really* scope the lock
    }   // scoped_lock destructor releases the lock
    
    {
        gl_group gl(GL_TRIANGLES); // calls glBegin()
        gl.Vertex3d( .. );
        gl.Vertex3d( .. );
        gl.Vertex3d( .. );
    } // gl_group destructor calls glEnd()
    
    < >在对象析构函数中,C++更有用(imHO);你的例子是用C写的

    想象一下,如果您创建了一个MutexLock类:

    class MutexLock {
    private:
        HANDLE handle;
    public:
        MutexLock() : handle(0) {
            GetMutexLock(handle);
        }
    
        ~MutexLock() {
            ReleaseMutexLock(handle);
        }
    }
    
    然后,您可以通过使用大括号提供新的作用域,将该锁的作用域仅限于需要它的代码:

    {
        MutexLock mtx;  // Allocated on the stack in this new scope
    
        // Use shared resource
    }
    // When this scope exits the destructor on mtx is called and the stack is popped
    

    如果要将代码放在大括号中,可能应该将其分解为自己的方法。如果它是一个单独的离散单元,为什么不给它贴上标签,并在功能上对它进行分解呢?这将明确块的作用,以后阅读代码的人将不必弄清楚。

    在原始示例中,
    {…}
    的具体位置纯粹用作格式化糖,使一组逻辑相关语句的开始位置和结束位置更加明显。如示例所示,它对已编译代码没有影响

    我不知道你所说的“如果互斥未被释放,这将导致编译器错误”是什么意思。那根本不是真的。使用
    {…}
    不能也不会导致任何编译器错误

    这是否是一个好的做法是个人喜好的问题。看起来不错。或者,您可以使用注释和/或缩进来指示代码中语句的逻辑分组,而不需要任何额外的
    {…}


    有各种各样的基于范围的技术,其中一些已经在这里的其他答案中得到了说明,但是你在你的OP中所拥有的甚至远不像那样。同样,OP中的内容(如图所示)纯粹是一种源代码格式习惯,具有多余的
    {…}
    ,对生成的代码没有影响。

    {I{认为{添加{大括号{可以{减少}可读性}}}}。说真的,大括号告诉我“这里有一个控制结构”。当没有的时候,我会一直寻找它。让我花费认知和几分之一秒的时间去寻找不存在的东西是不可读的。@David-我不认为OP会像你的例子那样在代码中添加任意数量的大括号。我指的是OP使用大括号的方式。很明显,在您的示例中添加大括号无助于提高可读性。就我而言,将大括号用于指示控件结构以外的任何目的都无助于提高可读性。这不算作控制结构。使用它们来限制RAII分配的资源的范围是非常困难的。您需要命名锁柜,否则它只是一个临时文件,会立即消失。并且您可能应该在它之后更改注释以匹配新的资源管理,而不是
    互斥锁(句柄)
    @KennyTM不是吗
    MutexLocker锁(句柄)?@Pedro:对。我认为
    handle
    是变量名:PI进入并修复了它。这是投票率最高的答案,不应该错得太多@赞恩:希望你不介意。在OpenGL中,这种做法是为了提高代码的可读性。glBegin()调用上的括号充当应该绘制的顶点组的可视定界器。这是一种糟糕的做法!我无法理解为什么有人会使用块分隔符来突出代码块。我可以想象所有的micr