クラスの基本/コピーコンストラクタ (C++をもう一度)
[履歴] [最終更新] (2014/12/09 09:17:36)
最近の投稿
注目の記事

サンプルコード

メンバ変数に配列が含まれている場合、関数等にオブジェクトを値渡しするためにはコピーコンストラクタを用意する必要があります。用意せずに値渡しすると、配列の先頭アドレスの値だけがコピーされ複数のオブジェクトで共有されることになり、片方のオブジェクトが破棄される際のデストラクタ処理などでアドレスが参照する先の領域が解放されてしまう恐れがあるためです。

#include <iostream>
#include <algorithm>
using namespace std;

class MyClass {
public:
    MyClass(int size);
    ~MyClass();
    MyClass(const MyClass& other); // コピーコンストラクタ

public:
    int Get(int i);

private:
    int m_size;
    int* m_intarr;
};

MyClass::MyClass(int size) {
    m_size = size;
    m_intarr = new int[size];
    fill_n(m_intarr, size, 0);
}

MyClass::~MyClass() {
    delete[] m_intarr;
}

MyClass::MyClass(const MyClass& other) {
    m_intarr = new int[other.m_size];
    m_size = other.m_size;

    // "algorithm" を include すると使用できる
    // (環境によっては他のヘッダファイルでもよい)
    copy(other.m_intarr, other.m_intarr + m_size, m_intarr);
    // ↑第一引数アドレス以降から第二引数アドレス未満にある値を、第三引数のアドレス以降にコピー
}

int MyClass::Get(int i) {
    return m_intarr[i];
}

void Show(MyClass obj) {
    // コピーされたので値を変更しても安心
    cout << obj.Get(0) << endl;
}

int main() {
    MyClass obj(2);

    Show(obj); // 値渡しが実現できる

    MyClass obj2(obj); // 応用。コピーコンストラクタによる変数初期化
    cout << obj2.Get(0) << endl;

    MyClass obj3 = obj; // このように記述してもよい
    cout << obj3.Get(0) << endl;
    return 0;
}
関連ページ