オブジェクトの配列

概要

自分で作ったオブジェクトの配列を作りたいことはよくある.特に,vectorで管理したいことはよくある.その時に,不要なコピーコンストラクタを呼ばないようにc++11以降ではpush_backの代わりにemplace_backを使う. emplace_backの引数はコンストラクタの引数として与えられる.引数を一つも取らない場合には空で実行する.

#include <iostream>
#include <string>
#include <vector>

class Person
{
private:
  std::string name;
public:
  Person() {
    cout << "default constructor" << endl;    
  };
  Person(std::string _name) {
    name = _name;
  };
  void hello() {std::cout << "I'm " << name << std::endl;};
};

int main()
{
  std::vector<std::string> names{"Nobunaga", "Ieyasu", "Hideyosi"};
  std::vector<Person> people;
  for (auto iter=names.begin(); iter != names.end(); ++iter)
    people.emplace_back(*iter);
  
  for (auto iter=people.begin(); iter != people.end(); ++iter)
    iter->hello();
  return 0;
}

ちなみに

ひさしぶりにC++を書こうとすると,いつコンストラクタが呼ばれるのかをいつも忘れて悩んでしまう.vectorで個数を指定して宣言する場合,初期化も行われる.このときは暗黙にデフォルトコンストラクタ(引数無しのコンストラクタ)が呼ばれる.

#include <iostream>
#include <string>
#include <vector>

class Person
{
private:
  std::string name;
public:
  Person() {
    cout << "default constructor" << endl;    
  };
  Person(std::string _name) {
    name = _name;
  };
  void hello() {std::cout << "I'm " << name << std::endl;};
};

int main()
{
  std::vector<std::string> names{"Nobunaga", "Ieyasu", "Hideyosi"};
  // それぞれの要素の初期化でコンストラクタが呼ばれる.この場合は3回.
  std::vector<Person> people(names.size());
 
  return 0;
}