C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++の均一初期化(Uniform Initialization)とは?基本構文と実践的な使い方を解説

本記事では、C++11から導入された「均一初期化(Uniform Initialization)」について詳しく解説します。均一初期化とは、プリミティブ型からアグリゲート(集約体)まで、あらゆる変数やオブジェクトを一貫した同じ構文で初期化できる機能のことです。具体的には、波括弧({})で初期化子の値を囲む「ブレース初期化(波括弧初期化)」と呼ばれる記法を指します。この記法により、これまで型ごとに異なっていた初期化の書き方を統一でき、コードの可読性と保守性が向上します。

基本構文

type var_name{argument_1, argument_2, .... argument_n}

動的確保した配列の初期化

new演算子で動的に確保した配列も、均一初期化を使えば宣言と同時に初期値をまとめて設定できます。

サンプルコード(C++)

以下の実装例で動作を確認してみましょう。

#include <bits/stdc++.h>
using namespace std;
int main() {
    int* pointer = new int[5]{ 10, 20, 30, 40, 50 };
    cout << "The contents of array are: ";
    for (int i = 0; i < 5; i++)
        cout << pointer[i] << " ";
}

実行結果

The contents of array are: 10 20 30 40 50

クラスの配列データメンバの初期化

クラスが持つ配列型のメンバ変数も、コンストラクタのメンバ初期化リストで波括弧を使うことで初期化できます。従来の方法では配列メンバをコンストラクタ内でまとめて初期化するのが面倒でしたが、均一初期化なら簡潔に記述可能です。

サンプルコード

#include <iostream>
using namespace std;
class MyClass {
    int arr[3];
    public:
        MyClass(int p, int q, int r) : arr{ p, q, r } {};
        void display(){
            cout << "The contents are: ";
            for (int c = 0; c < 3; c++)
                cout << *(arr + c) << ", ";
    }
};
int main() {
    MyClass ob(40, 50, 60);
    ob.display();
}

実行結果

The contents are: 40, 50, 60,

戻り値として返すオブジェクトの暗黙的な初期化

関数のreturn文では、クラス名を明示せずに波括弧だけでオブジェクトを生成して返すことができます。コンストラクタに対応する引数を波括弧で渡すだけで、暗黙的にオブジェクトが構築されます。

サンプルコード

#include <iostream>
using namespace std;
class MyClass {
    int p, q;
public:
    MyClass(int i, int j) : p(i), q(j) {
    }
    void display() {
        cout << "(" << p << ", " << q << ")";
    }
};
MyClass func(int p, int q) {
    return { p, q };
}
int main() {
    MyClass ob = func(40, 50);
    ob.display();
}

実行結果

(40, 50)

関数引数の暗黙的な初期化

関数に引数を渡す際も、同様に波括弧だけでオブジェクトをその場で生成して渡せます。一時オブジェクトを明示的に作成する必要がなく、呼び出し側のコードがすっきりします。

サンプルコード

#include <iostream>
using namespace std;
class MyClass {
    int p, q;
public:
    MyClass(int i, int j) : p(i), q(j) {
    }
    void display() {
        cout << "(" << p << ", " << q << ")";
    }
};
void func(MyClass p) {
    p.display();
}
int main() {
    func({ 40, 50 });
}

実行結果

(40, 50)

このように均一初期化を活用すると、動的配列・クラスのメンバ配列・戻り値・関数引数など、さまざまな場面で共通の構文による初期化が可能になり、C++コード全体の統一感が高まります。

  1. C++で解くリスのナッツ収集シミュレーション ― 最小移動距離を求めるアルゴリズム

    問題概要 1本の木、1匹のリス、そして複数のナッツがフィールド上にあります。それぞれの位置は2次元グリッドのセルで表現されます。この問題の目的は、リスがすべてのナッツを集めて木の下に1個ずつ運ぶときの最小移動距離を求めることです。 リスの行動には次の制約があります。 一度に持てるナッツは最大1個 移動は上下左右の4方向で、隣接するセルへのみ可能 距離は移動回数(ステップ数)で表される たとえば、入力が「高さ: 5 / 幅: 7 / 木の位置: [2,2] / リスの位置: [4,4] / ナッツ: [[3,0], [2,5]]」の場合、出力は 12 となります。 解法のポイント まず、

  2. C++で解く長方形エリアII ― 座標圧縮と走査線法による被覆面積の計算

    問題概要 軸に平行な長方形のリストが与えられるものとします。各 rectangle[i] = {x1, y1, x2, y2} において、(x1, y1) は i 番目の長方形の左下隅の座標、(x2, y2) は右上隅の座標を表します。 求めたいのは、平面上でこれらすべての長方形が覆っている領域の合計面積です。答えは非常に大きな値になる可能性があるため、109 + 7 で割った余りを返すことになっています。 たとえば、入力が次のような場合を考えてみましょう。 このとき、出力は 6 となります。 解法の方針:座標圧縮+走査線(スイープライン) この問題は、座標圧縮(座標の離散化)と走査線法(