object slicing

object slicing發生在衍生類別的物件複製到基類時,預設只複製基類的成員,這時候在衍生類別的資訊會遺失。

這樣有可能造成在執行method或是destructor因為遺失了資訊而造成其他錯誤。
當複製為參考時(base class reference type),則不會有此問題。

object slicing的問題,在exception catch時要特別注意,應該要catch reference(catch(A& a)才不會造成object slicing),而不是catch value

如下面範例: 如果是 catch(A a) 會走copy ctor的路,因為是將B()複製到a,而造成object slicing,並且因為copy後,catch到的物件已經不是當時拋出的那個物件了

#include <iostream>

class A
{
public:
  A(const A&)
  {
    std::cout << "A(const A&):" << this <<std::endl;
  }
  A()
  {
    std::cout << "A():" << this <<std::endl;
  }
};

class B: public A
{
public:
  B(const B&)
  {
    std::cout << "B(const B&):" << this <<std::endl;
  }
  B()
  {
    std::cout << "B():" << this <<std::endl;
  }
};

int main()
{
  try
  {
    throw B();
  }
  catch(A a)
  {
    std::cout << "catch A" << std::endl;
  }
  return 0;
}

參考:
https://en.wikipedia.org/wiki/Object_slicing
https://stackoverflow.com/questions/274626/what-is-object-slicing
http://ptgmedia.pearsoncmg.com/images/0321113586/items/sutter_item73.pdf

This entry was posted in C++ idioms. Bookmark the permalink.

Leave a Reply