C++核心准则C.90:依靠构造函数和赋值运算符,而不是内存初始化和...
青金石
C.90: Rely on constructors and assignment operators, not memset and memcpy
C.90:依靠构造函数和赋值运算符,而不是内存初始化和内存拷贝
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++机制通过调用构造函数构造某个类型的实例。正如C.41说明的:构造函数应该生成一个完全初始化的对象。不应该要求额外的初始化,例如使用memcpy。类型应该提供一个拷贝构造函数和/或者拷贝复制运算符以便适当地生成类的拷贝并维持类的不变量。使用memcpy拷贝一个非平常可拷贝类型的行为没有定义。通常会导致断层或者数据破坏。
Example, good(范例)
struct base
{
virtual void update() = 0;
std::shared_ptrsp;
};
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.
这个函数类型不安全而且会覆盖虚函数表。
Example, bad(反面示例)
void copy(derived& a, derived& b)
{
memcpy(&a, &b, sizeof(derived));
}
This is also type-unsafe and overwrites the vtable.
这个函数同样是类型不安全而且覆盖虚函数表。
Enforcement(实施建议)
Flag passing a non-trivially-copyable type to memset or memcpy.
提示向memset或memcpy传递非平凡可拷贝类型的处理。
关于平凡拷贝请参见:
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
觉得本文有帮助?请分享给更多人。
关注【面向对象思考】轻松学习每一天!
面向对象开发,面向对象思考!