より良いエンジニアを目指して

1日1つ。良くなる!上手くなる!

オブジェクトを=で代入したらコピー

C++の場合、以下のようにオブジェクトを代入したらコピーになります。

MyClass obj2 = obj1;

obj2とobj1は別のオブジェクトです。

#include <iostream>
using namespace std;

class MyClass {
public:
    int data;
};

int main() {
    MyClass obj1 = MyClass();
    obj1.data = 123;
    MyClass obj2 = obj1; // これはコピー

    cout << "obj1 = " << obj1.data << endl; // 123
    cout << "obj2 = " << obj2.data << endl; // 123

    obj1.data = 456;

    cout << "obj1 = " << obj1.data << endl; // 456
    cout << "obj2 = " << obj2.data << endl; // 123のまま

    return 0;
}

f:id:rimever:20190816063249p:plain

これに不思議に感じたのは私が、C#に慣れきっているためです。

using System;
                    
public class Program
{
    public class MyClass {
        public int data {get; set;}
    }

    public static void Main()
    {
        MyClass obj1 = new MyClass();
        obj1.data = 123;
        MyClass obj2 = obj1;
        Console.WriteLine(obj1.data); //123
        Console.WriteLine(obj2.data); //123

        obj1.data = 456;
        Console.WriteLine(obj1.data); //456
        Console.WriteLine(obj2.data); //456
    }
}

f:id:rimever:20190816063326p:plain

C#の場合は、オブジェクトを代入したら参照型です。

では、C#のように参照型としてシャローコピーにしたい場合は?

C++の代名詞である、ポインタの出番ですね。

#include <iostream>
using namespace std;

class MyClass {
public:
    int data;
};

int main() {
    MyClass obj1 = MyClass();
    obj1.data = 123;
    MyClass* obj2 = &obj1; // これはポインタ

    cout << "obj1 = " << obj1.data << endl; // 123
    cout << "obj2 = " << obj2->data << endl; // 123

    obj1.data = 456;

    cout << "obj1 = " << obj1.data << endl; // 456
    cout << "obj2 = " << obj2->data << endl; // 456


    return 0;
}

f:id:rimever:20190816063407p:plain

ポインタがあるんだから、同じ挙動なわけないんですが、改めて動かすと不思議に思ったものでした。