C++核心准则C.90:依靠构造函数和赋值运算符,而不是内存初始化和...

面向对象思考

共 1679字,需浏览 4分钟

 · 2020-01-24

1cd43c2cf72a7ee8b41babfa1602e09f.webp

青金石

C.90: Rely on constructors and assignment operators, not memset and memcpy

C.90:依靠构造函数和赋值运算符,而不是内存初始化和内存拷贝‍


0110fc30df01f1bfa902ce13e064996d.webp

Reason(原因)

0110fc30df01f1bfa902ce13e064996d.webp

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拷贝一个非平常可拷贝类型的行为没有定义。通常会导致断层或者数据破坏。


a17956ed3f0f85adc417c4724754aa42.webp

Example, good(范例)


struct base
{
    virtual void update() = 0;
    std::shared_ptr sp;
};


struct derived : public base
{
    void update() override {}
};


89aaa9051eba9949b66a68f0dad7c2e0.webp

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.

这个函数同样是类型不安全而且覆盖虚函数表。


c6d938bdbf404743bb0be41facff1a58.webp7d815f816558abc9d7419b18cc6779c8.webp

Enforcement(实施建议)‍

265545dad9a55c62649876a2a945eeb4.webp

  • Flag passing a non-trivially-copyable type to memset or memcpy.

  • 提示向memset或memcpy传递非平凡可拷贝类型的处理。


关于平凡拷贝请参见:

https://zh.cppreference.com/w/cpp/named_req/TriviallyCopyable‍




a7f53de51804e5be84eb5214f4767e73.webp

原文链接

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c90-rely-on-constructors-and-assignment-operators-not-memset-and-memcpy




觉得本文有帮助?请分享给更多人。

关注【面向对象思考】轻松学习每一天!

面向对象开发,面向对象思考!



浏览 26
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报