copy struct 使用memcpy 的壞處

我有一個 class 的 method,可以用來讓人讀值。裡面使用 memcpy 來為傳入的參數做給值,他會依照 class Property1 的大小 sizeof(Property1),來做 memcpy 的 copy 範圍參考。

class Property1{};

class MyClass
{public:
  void get_property1(Property1* p_property) const
  {
    memcpy(p_property, &m_property1, sizeof(Property1));
  }
 private:
  Property1 m_property1;
};

今天要把我的 Property1 升級成二代,同時也將參數也改成二代 type,按下 compile 沒報錯。很好,可以洗洗睡了。

殊不知別人怎麼 query 我的 get_property1, 就是 query 不到新增的值。結果在於 memcpy 的範圍還是寫成 sizeof(Property1),於是乎只複製了舊 type 的 fields。但是 compiler 就是很安靜,不跟你說錯了。

class Property1{};
class Property1_v2 : public Property1 {};

class MyClass
{public:
  void get_property1(Property1_v2* p_property) const
  {
    memcpy(p_property, &m_property1, sizeof(Property1));
  }
 private:
  Property1_v2 m_property1;
};

解法: 就使用好用的 assignment operator,讓給值進入 typed system。

class Property1{};
class Property1_v2 : public Property1 {};

class MyClass
{public:
  void get_property1(Property1_v2* p_property) const
  {
    *p_property = m_property1;
  }
 private:
  Property1_v2 m_property1;
};

這樣子就算參數的型別忘了改,compiler 還是會貼心地提醒你。

comments powered by Disqus