読者です 読者をやめる 読者になる 読者になる

Flat Leon Works

アプリやゲームを作ってます。

【C++ 小ネタ】ブロック文を活用する

C++ 技術

ブロック文とは

C++にはブロック文というものが存在します。ブロック、あるいは複合文とも呼ばれます。

// これがブロック文
{
    // ここはブロックスコープとなる
}

ブロック文はスコープを作り出すだけで、特に意味のない存在のように見えますが、実は結構便利な構文なのです。

ブロック文の利用場面

ブロック文は言語機能的には変数の可視範囲と寿命を定めるだけの機能、つまりスコープを生むための機能なのですが、ブロック文を利用することのメリットはたくさんあります。

  • 変数の利用範囲を狭めることで、コードの可読性があがる
  • 変数名の使い回しができるようになる
  • 処理のかたまりを表すことができる
  • RAIIイディオムのお供に

変数の利用範囲を狭めることで、コードの可読性があがる

int a = 0;
{
    int b = 0;
    〜 処理 〜
}

変数aはブロック外にもブロック内でも出現する可能性がありますが、ブロック内で定義された変数bはブロック外で利用されることはないので、変数bの利用範囲がブロック内のみだとすぐにわかります。

変数名の使い回しができるようになる

// Aの数を数えて出力する
{
    int count = 0;
    〜 処理 〜
}
// Bの数を数えて出力する
{
    int count = 0; // ここでもcountという名前が利用可能
    〜 処理 〜
}

最初のブロックで定義された変数countはブロックを抜けたあとには完全に見えなくなるので、再びcountという名前の変数を定義できるようになります。

処理のかたまりを表すことができる

ブロック文でインデントを行うことで処理のかたまりを視覚的に表すことができます。またブロック文の前にコメントを記述することで処理のかたまりの説明を記述することができます。

// ○○を行う
{
    〜 処理 〜
}

関数に分けるべきとの意見もあると思いますが、そこは可読性や処理の再利用性などを考えてどちらを採用するか考えるべきだと思います。数行以内で他では利用しない処理はわざわざ関数化する必要はないと思います。

RAIIイディオムのお供に

class Profiler
{
public:
    Profiler(){ printf( "Enter Block %d\n", GetTime() ); }
    ~Profiler(){ printf( "Leave Block %d\n", GetTime() ); }
};
{
    Profiler profiler;
    〜 処理 〜
}

このProfilerクラスはコンストラクタとデストラクタで時間を標準出力するので、Profilerクラスとブロック文を使うことで簡単に任意のブロックの処理時間を計測することができるようになります。これはRAII*1と呼ばれるC++のイディオムを利用したもので、ブロック文の便利な使い方の一つだと思います。

まとめ

ブロック文は意外と便利。