c++ - 为什么不能对具有析构函数的类进行 memcpy

标签 c++

C++ 的规则表明使用 memcpy 复制对象或 POD 类型是合法的并且可以工作。

他们进一步说 POD 不能有(非平凡的)析构函数。为什么会这样,为什么仅添加析构函数就会以使用 memcpy 不起作用的方式更改类?

// Perfectly fine to copy using memcpy
struct data
{
    int something;
    float thing;
};

// Not allowed to copy using memcpy
int var;

struct data
{
    int something;
    float thing;
    ~data() { var = 1; }
};

为什么简单地添加析构函数就无法 memcpy 结构的数据?我无法想象这需要以任何方式更改数据布局。

我不想被告知不要这样做,我无意这样做......我知道我不能这样做,因为“标准是这样说的”,但我想知道原因是什么标准这么说是因为它对我来说似乎不是必要的限制并且想了解原因。

编辑 人们似乎误解了我的问题。我不是在问使用 memcpy 是否是个好主意。我问的是,如果存在非平凡的析构函数,将其设为非法的原因是什么。我看不出它有什么不同,并且想了解为什么存在此限制。无论是否有析构函数,我得到的关于它是一个坏主意的大多数理由都同样适用。

最佳答案

通俗地说:

Why would simply adding the destructor make it impossible to memcpy the struct's data?

这并不意味着不可能,只是非法。

I can't imagine that this would require altering the data layout in any way.

可能不会,但这是允许的。因为该类不再是 POD(即 C 结构),所以它现在是 C++ 类。

类与 POD 有不同的规则。由于我们无法预测编译器将如何对它们进行编码,因此我们无法再推断 memcpy 的结果。

关于c++ - 为什么不能对具有析构函数的类进行 memcpy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39614593/

相关文章:

c++ - 这个 Visual Studio 编译器错误 'divide or mod by zero' 是一个错误吗?

c++ - C++ 中的运行时位复制(位掩码)

c++ - 有没有办法让点 (.) 匹配 C++ TR1 正则表达式中的换行符?

c++ - 不使用 sprintf 或 to_string 将值插入字符串

c++ - 类型转换的原理是什么?

c++ - C++ 中带有 malloc 的字符串数组

c++ - 有没有办法避免严格的别名警告?

c++ - 为什么这个 lambda 可以流式传输?

c++ - 了解 C++ 函数内联

c++ - ATLGetDacl 从 32 位进程访问 64 位注册表键