オブジェクトの配列
概要
自分で作ったオブジェクトの配列を作りたいことはよくある.特に,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; }