[[ssacontents]] C++において、オブジェクトのスライシングとは、 class base { int a; virtual const char* name() { return "base"; } }; class sub : public base { int b; virtual const char* name() { return "sub"; } }; void hoge(base& b) { printf("%s\n", b.name()); base tmp = b; printf("%s\n", tmp.name()); } sub s; hoge(s); ... hoge()では、"base"が表示される。 hoge()では、"sub","base"が表示される。~ 文法的には正しいので、警告はでない。このミスを見つけるのは困難。~ これを未然に防ぐには、工数がかかるけど以下のようにする。 class base { int a; base() : a(0) {} base(const base& b) : a(b.a) {} virtual ~base() {} virtual const char* name() { return "base"; } virtual base* clone() { return new base(*this); } static void destroy(base* b) { delete b; } private: void operator = (const base&); }; class sub : public base { int b; sub() : b(0) {} sub(const sub& s) : base(s), b(s.b) {} virtual ~sub() {} virtual const char* name() { return "sub"; } virtual base* clone() { return new sub(*this); } }; void hoge(base& b) { printf("%s\n", b.name()); base* tmp = b->clone(); // base tmp = b;ではビルドエラー printf("%s\n", tmp->name()); base::destroy(tmp); // baseとしてdeleteされるので仮想デストラクタ必須 } sub s; hoge(s); ... hoge()では、"sub","sub"が表示される。~