char型配列を含むクラスを格納したvectorのコピー

using namespace std;

struct Hoge final
{
    int a;
    char name[3]{}; // 要素を0で初期化
};

int main()
{
    Hoge a{};
    a.a = 10;
    a.name[0] = 'a';
    a.name[1] = 'b';
    std::vector<Hoge> v1{};
    v1.push_back(a); // Hogeのコピーコンストラクタが実行される
    
    std::vector<Hoge> v2{};
    v2 = v1; // vectorのコピー。各要素をコピーする度、Hogeのコピーコンストラクタが実行される
    
  // コピー元を書き換えてみる
    a.a = 3; 
    v1.at(0).name[1]='c';
    
    // コピー先を出力
    cout << v2.at(0).a << endl;
    cout << v2.at(0).name << endl;
}

実行結果
10
ab

配列を含むvectorをv2 = v1でコピーしたら、要素毎にコピーコンストラクタが実行され、メンバ変数nameの全要素もコピーされているので、コピー元を書き換えても問題ないっぽい。
nameの先頭ポインタだけがコピーされるシャローコピーではなく、ディープコピーされている?
少なくとも、char[]に関しては問題なく全要素コピーされている模様。
ただし、もし、Mosa* ptrのように、メンバ変数にポインタを保持している場合は、ポインタの先頭アドレスしかコピーされず、コピー先の編集がコピー元に影響を与えるなどが発生するのではなかろうか(要確認)

追記

v2 = v1よりもstd::copyを使った方がよさげ。

std::vector<Hoge> v2{};
v2.clear(); // 繰り返し呼び出すような箇所はクリア必須
v2.reserve(v1.size()); // なくてもいいが、こちらの方がcapacityがコピー元配列のsize未満だった場合にallocationが発生するのを予防でき、メモリ断片化を防げるらしい。
std::copy(v1.begin(), v1.end(), std::back_inserter(v2));

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です