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