我可以防止对象被 std::memcpy 复制吗?

Can I prevent object from being copied by std::memcpy?

使用私有复制构造函数和赋值运算符 boost::noncopyable 或 C++11 delete 关键字可以轻松实现不可复制 class:

class MyClass {
private:
    int i;
public:
    MyClass(const MyClass& src) = delete;
    MyClass& operator=(const MyClass& rhs) = delete;    
    int getI() {
        return i;
    }
    MyClass(int _i) : i(_i){}
};

int main() {
    MyClass a(1), b(2);
    a = b; // COMPILATION ERROR
}

然而,这并不能阻止对象作为字节包被深度复制:

int main() {
    MyClass a(1), b(2);   
    std::memcpy(&a, &b, sizeof(MyClass));
    std::cout << a.getI() << std::endl; // 2
}

即使尝试通过声明 operator& private 来阻止它,仍然可以使用 address-of idiom 的实现进行复制:

int main() {
    MyClass a(1), b(2);   
    std::memcpy(std::addressof(a), std::addressof(b), sizeof(MyClass));
    std::cout << a.getI() << std::endl; // 2
}

有什么方法可以完全防止一个实例被逐字节复制吗?

Can I prevent object from being copied by std::memcpy?

简单的答案是 "No"。

这不是万无一失的,但您可以实现自己的 memcpy_safe,其行为类似但接受 void* 以外的内容。然后创建一个包含

的包含文件
#define memcpy memcpy_old
#include <cstring>
#undef memcpy
#define memcpy memcpy_safe

并告诉人们改用这个包含文件。它所做的是隐藏 memcpy 的声明,并将对 memcpy 的所有调用替换为对 memcpy_safe 的调用。新功能需要在自己的翻译单元中实现,所以可以调用旧的memcpy.