[[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()では、"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()では、"base"が表示される。

hoge()では、"sub","sub"が表示される。~


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS