C++核心準則C.90:依靠構(gòu)造函數(shù)和賦值運算符,而不是內(nèi)存初始化和...

青金石
C.90: Rely on constructors and assignment operators, not memset and memcpy
C.90:依靠構(gòu)造函數(shù)和賦值運算符,而不是內(nèi)存初始化和內(nèi)存拷貝?

Reason(原因)

The standard C++ mechanism to construct an instance of a type is to call its constructor. As specified in guideline C.41: a constructor should create a fully initialized object. No additional initialization, such as by memcpy, should be required. A type will provide a copy constructor and/or copy assignment operator to appropriately make a copy of the class, preserving the type's invariants. ?Using memcpy to copy a non-trivially copyable type has undefined behavior. ?Frequently this results in slicing, or data corruption.
標準C++機制通過調(diào)用構(gòu)造函數(shù)構(gòu)造某個類型的實例。正如C.41說明的:構(gòu)造函數(shù)應(yīng)該生成一個完全初始化的對象。不應(yīng)該要求額外的初始化,例如使用memcpy。類型應(yīng)該提供一個拷貝構(gòu)造函數(shù)和/或者拷貝復制運算符以便適當?shù)厣深惖目截惒⒕S持類的不變量。使用memcpy拷貝一個非平??煽截愵愋偷男袨闆]有定義。通常會導致斷層或者數(shù)據(jù)破壞。

Example, good(范例)
struct?base
{
????virtual?void?update()?=?0;
????std::shared_ptr?sp;
};
struct?derived?:?public?base
{
????void?update()?override?{}
};

Example, bad(反面示例)
void?init(derived&?a)
{
????memset(&a,?0,?sizeof(derived));
}
This is type-unsafe and overwrites the vtable.
這個函數(shù)類型不安全而且會覆蓋虛函數(shù)表。
Example, bad(反面示例)?
void?copy(derived&?a,?derived&?b)
{
????memcpy(&a,?&b,?sizeof(derived));
}
This is also type-unsafe and overwrites the vtable.
這個函數(shù)同樣是類型不安全而且覆蓋虛函數(shù)表。


Enforcement(實施建議)?

Flag passing a non-trivially-copyable type to memset or memcpy.
提示向memset或memcpy傳遞非平凡可拷貝類型的處理。
關(guān)于平凡拷貝請參見:
https://zh.cppreference.com/w/cpp/named_req/TriviallyCopyable?

原文鏈接
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c90-rely-on-constructors-and-assignment-operators-not-memset-and-memcpy
覺得本文有幫助?請分享給更多人。
關(guān)注【面向?qū)ο笏伎肌枯p松學習每一天!
面向?qū)ο箝_發(fā),面向?qū)ο笏伎迹?/span>
