14

スコープとは何の関係もなく、読みやすさとミスの回避のためだけに余分な中かっこを含むコードに出くわすことがあります。

例えば:

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()呼び出しの両方を覚えていると仮定します)。

  1. これは悪い習慣ですか?なんで?
  2. そうでない場合、コードのコンパイル方法を変更したり、遅くしたりできますか?
4

8 に答える 8

34

中かっこ自体は問題ありません。中かっこはスコープを制限するだけで、速度が低下することはありません。クリーナーとして見ることができます。(高速コードよりもクリーンコードを常に優先します。クリーンな場合は、プロファイルを作成するまで速度について心配する必要はありません。)


しかし、リソースに関しては、リソースをリークする立場にあるため、これは悪い習慣です。ブロック内の何かがスローまたはリターンした場合、あなたは死んでいると強打します。

デストラクタを使用して、リソースをスコープに制限するスコープバインドリソース管理(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
}

これを行うと、すべてのリソースがよりクリーンで安全になります。「このリソースをリリースする必要があります」と言う立場にある場合は、間違っています。それらは自動的に処理される必要があります。

于 2010-08-25T17:20:33.497 に答える
18

中括弧は変数スコープに影響します。私の知る限り、彼らがしているのはそれだけです。

はい、これはプログラムのコンパイル方法に影響を与える可能性があります。デストラクタは、関数の終わりまで待つのではなく、ブロックの終わりに呼び出されます。

多くの場合、これはあなたがやりたいことです。たとえば、GetMutexLockと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またはプログラムのクラッシュまたはアボートを除いて、例外を含むすべての状況でリリースされます。

于 2010-08-25T17:20:10.153 に答える
3

元の例の の特定の配置は{ ... }、論理的に関連するステートメントのグループがどこで始まり、どこで終わるかをより明確にすることで、純粋に砂糖の書式設定として機能します。あなたの例に示されているように、コンパイルされたコードには影響しません。

「ミューテックスが解放されていない場合、これによりコンパイラエラーが発生する」という意味がわかりません。それは単に真実ではありません。をこのように使用して{ ... }も、コンパイラ エラーが発生することはありません。

それが良い習慣であるかどうかは、個人の好みの問題です。それは大丈夫に見えます。または、コメントやインデントを使用して、コード内のステートメントの論理グループを示すことができます。余分な{ ... }.

そこにはさまざまなスコーピングベースの手法があり、そのうちのいくつかはここの他の回答で示されていますが、OP にあるものはリモートでそのように見えることさえありません。繰り返しますが、OP にあるもの (示されているように) は{ ... }、生成されたコードに影響を与えない余分な要素を含む純粋なソース形式の習慣です。

于 2010-08-25T17:32:33.403 に答える
3

それは悪い習慣ではありません。それは何も遅くしません。これは、コードを構造化する方法にすぎません。

コンパイラにエラーチェックと強制を実行させることは、常に良いことです!

于 2010-08-25T17:15:19.500 に答える
2

コンパイラが完全に正気でない限り、周囲のブロックの最後ではなく、そのブロックの最後でデストラクタを呼び出すことを除けば、コンパイルされたコードに違いはありません。

個人的には、私はそれを悪い習慣と呼んでいます。ここで犯す可能性のある間違いを避ける方法は、エラーが発生しやすいタイポグラフィのリマインダーを使用せずに、範囲指定されたリソース管理 (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()
于 2010-08-25T17:21:48.313 に答える
2

コードを中かっこに入れる場合は、おそらくそれを独自のメソッドに分割する必要があります。それが単一の個別のユニットである場合、ラベルを付けて機能的に分割してみませんか? これにより、ブロックの機能が明確になり、後でコードを読んだ人は理解する必要がなくなります。

于 2010-08-25T17:26:07.387 に答える
1

読みやすさを向上させるものは何でもIMHOは良い習慣です。中かっこを追加すると読みやすさが向上する場合は、それを選択してください。

中括弧を追加しても、コードのコンパイル方法は変わりません。プログラムの実行が遅くなることはありません。

于 2010-08-25T17:17:18.527 に答える
1

これは、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
于 2010-08-25T17:22:22.380 に答える