#12 クラスのコピーの仕方3 STLコンテナを使うとき

Effective C++ 12項の内容+αの内容になりますが,STLのコンテナを使うときにコピーコンストラクタ・コピー代入演算子がどのように働くかを見てみます.

下記のサンプルコードを作ってみました.

#include <iostream>
#include <memory>
#include <cstring>
#include <vector>

class MyContainer {
public:

  MyContainer() 
    : a(0), b(0)
  {
    std::cout << "MyContainer()" << std::endl;
  }

  ~MyContainer()
  {
    std::cout << "~MyContainer()" << std::endl;
  }

  MyContainer(const MyContainer& obj) 
    : a(obj.a), b(obj.b)
  {
    std::cout << "MyContainer(const MyContainer& obj)" << std::endl;    
  }

  MyContainer& operator=(const MyContainer& obj) {
    std::cout << "MyContainer& operator=(const MyContainer& obj)" << std::endl;
    if (this != &obj) {
      this->a = obj.a;
      this->b = obj.b;
    }
    return *this;
  }

  int a, b;
};

int main(int, char**) {

  std::cout << __FILE__ << std::endl;

  MyContainer cont1;

  std::cout << std::endl;
  std::cout << "Start of vector scope." << std::endl;
  {
    std::vector<MyContainer> vec;
    vec.push_back(cont1);
  }
  std::cout << "End of vector scope." << std::endl;
  std::cout << std::endl;

  return 0;
}

上記のコードを実行すると,下記の結果になります.

MyContainer()

Start of vector scope.
MyContainer(const MyContainer& obj)
~MyContainer()
End of vector scope.

~MyContainer()

で,上記を見てわかると思うのですが,STLのベクタに要素をプッシュした場合,コピーコンストラクタが呼ばれていることがわかります.で,vectorのが定義されたスコープの外に出ると,vectorが廃棄されるときにvectorに入れられている要素のデストラクタが呼ばれていることがわかります.ということで,自作オブジェクトに対してSTLを使用する場合,,,

1.コピー戦略として,ディープコピーを採用しているオブジェクトならそのまま使える.(ディープコピーがちゃんと実装されていればですが..)

2.コピー戦略として,シャローコピーを採用しているオブジェクトの場合,共有している領域のリークや二重解放が起こらないようにかなり慎重に作る必要がある.

という感じでしょうか.