C++:オーバーロードについて > コンストラクタのオーバーロード(1)

C++の関数のオーバーロードの中からコンストラクタのオーバーロードについてのメモ。

オーバーロードについて

コンストラクタをオーバーロードする目的は次の3つ。

  • 柔軟性を得る
  • 配列をサポートする
  • コピーコンストラクタを作成する

柔軟性を得る

オブジェクトの初期化をするかしないかを選択できるようにする。

サンプルコード
#include <iostream>
using namespace std;

class Sample {
    int x;
    
public:
    Sample() { x = 0; }
    Sample( int n) { x = n; }
    int get_val() { return x; }
};

int main(int argc, const char * argv[])
{
    Sample obj1;
    Sample obj2(10);
    
    cout << "obj1: " << obj1.get_val() << "\n";
    cout << "obj2: " << obj2.get_val() << "\n";
    
    return 0;
}
[/code]</dd>
</dl>
<dt>結果</dt>
<dd>
[code]
obj1: 0
obj2: 10

配列をサポートする

動的配列は初期化することが出来ないため、初期値を受け取るコンストラクタがある場合、初期値を受け取らないコンストラクタをオーバーロードする必要がある。

サンプルコード
#include <iostream>
using namespace std;

class Sample {
    int x;
    
public:
    Sample() { x = 0; }
    Sample(int n) { x = n; }
    int get_val() { return x; }
    void set_val(int n) { x = n; }
};

int main(int argc, const char * argv[])
{
    Sample obj(10);
    Sample *p;
    
    p = new Sample[5];
    if (!p) {
        cout << "error\n";
        return 1;
    }
    
    int i;
    
    for (i=0; i<5; i++) {
        p[i] = obj;
    }
    
    for (i=0; i<5; i++) {
        cout << "p[" << i << "]: " << p[i].get_val() << "\n";
    }
    
    return 0;
}
[/code]
</dd>
<dt>結果</dt>
<dd>
[code]
p[0]: 10
p[1]: 10
p[2]: 10
p[3]: 10
p[4]: 10

コピーコンストラクタを作成する

関数にオブジェクト渡したり関数からオブジェクトを返すとき、一時的にオブジェクトのコピーが生成されるため、デストラクタが複数回実行され、望ましくない影響が出る可能性がある。

オブジェクトのコピー生成時の実行処理を定義するために、コピーコンストラクタを作成しオブジェクトのコピーが生成されるときの処理を正確に指定することができる。

コピーコンストラクタの定義
クラス名 (const クラス名 &obj) {
    // 処理
}
サンプルコード
#include <iostream>
#include <cstdlib>
using namespace std;

class Sample {
    int *p;
    int size;
    
public:
    // コンストラクタ
    Sample(int n) {
        p = new int[n];
        if(!p) exit(1);
        size = n;
        cout << "コンストラクタ\n";
    }
    
    // デストラクタ
    ~Sample() {
        delete [] p;
        cout << "デストラクタ\n";
    }
    
    //コピーコンストラクタの定義
    Sample(const Sample &a);
    
    void set_val(int i, int j) {
        if (i>=0 && i<size) {
            p[i] = j;
        }
    }
    
    int get_val(int i) { return p[i]; }
};

// コピーコンストラクタの実装
Sample::Sample(const Sample &a) {
    int i;
    size = a.size;
    p = new int[a.size];
    if(!p) exit(1);
    for (i=0; i<a.size; i++) {
        p[i] = a.p[i];
    }
    cout << "コピーコンストラクタ \n";
}

int main(int argc, const char * argv[])
{
    int i;
    
    // 配列作成(コンストラクタ呼び出し)
    Sample num(10);
    for (i=0; i<10; i++) {
        num.set_val(i, i);
    }
    
    // 値を格納
    for (i=0; i<10; i++) {
        cout << num.get_val(i);
    }
    
    cout << "\n";
    
    // 配列作成(コピーコンストラクタ呼び出し)
    Sample x = num;
    
    // x出力
    for (i=9; i>=0; i--) {
        cout << x.get_val(i);
        
    }
    cout << "\n";
    
    return 0;
}
[/code]
</dd>

<dt>結果</dt>
<dd>
[code]
コンストラクタ
0123456789
コピーコンストラクタ 
9876543210
デストラクタ
デストラクタ
補足説明
  • コピーコンストラクタは初期化の状況にしか対処出来ない(代入には使用できない)

まとめ

この記事がみなさんのお役に立ちましたら、下記「Share it」よりブックマークやSNSで共有していただければ幸いです。

siro:chro 無料ゲーム SQN をリリースしました

img_sqn_00

sirochro 初の無料ゲームアプリ SQN をリリースしました。
記事:SQN: iOS 無料ゲームアプリ SQN - Sequential Numbers をリリース
ちょっとした時間に楽しめる完全無料のゲームなっていますので、是非ダウンロードして遊んでみてください。

↓SQN のダウンロードはこちらから

Related Contents

Pickup Contents