24 November 2022

C++ 核心指南目录

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

理由

在标准C++机制中,创建一个实例的方法是调用实例类的构造函数。参考 C.41 构造函数应该创建一个完全初始化的对象,而不需要额外的初始化工作如 memcpy 等操作。一个类型还会提供拷贝构造函数和/或拷贝赋值函数,实现类型的拷贝,从而保留类型的不变式约束。使用 memcpy 拷贝可拷贝的复杂类型会导致未定义的行为。经常会导致类切片( slicing )和数据损坏(data corruption)。

例子

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

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

例子

void init(derived& a)
{
    memset(&a, 0, sizeof(derived));
}

这种初始化方式会导致类型不安全,覆盖虚函数表。

例子

void copy(derived& a, derived& b)
{
    memcpy(&a, &b, sizeof(derived));
}

以上操作也是会导致类型不安全,覆盖虚函数表。

强化

  • 标记传递复杂类型给 memsetmemcpy 的操作