简体   繁体   English

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

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

It's easy to make noncopyable class with private copy construcor and assignment operator, boost::noncopyable or the C++11 delete keyword: 使用私有拷贝construcor和赋值运算符, boost::noncopyable或C ++ 11 delete关键字很容易创建不可复制的类:

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
}

However this doesn't prevent obiect from being deep copied as a pack of bytes: 但是,这并不能防止obiect被深度复制为一个字节包:

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

Even if try to prevent it by declaring operator& private, it's still possible to make copy using implementations of address-of idiom: 即使试图通过声明operator&私有来阻止它,仍然可以使用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
}

Is there any method to completely prevent an instance from being copied byte per byte? 有没有任何方法可以完全防止每个字节复制一个实例?

Can I prevent object from being copied by std::memcpy ? 我可以阻止std::memcpy复制对象吗?

The simple answer is "No". 简单回答是不”。

This is not bullet-proof but you can implement your own memcpy_safe that behaves similarly but accepts something else than void* . 这不是防弹,但你可以实现自己的memcpy_safe ,其行为类似但接受除void*其他内容。 Then you create an include file that contains 然后创建一个包含的包含文件

#define memcpy memcpy_old
#include <cstring>
#undef memcpy
#define memcpy memcpy_safe

And tell people to use this include file instead. 并告诉人们使用这个包含文件。 What it does is to hide the declaration of memcpy , and replaces all calls to memcpy with calls to memcpy_safe . 它的作用是隐藏memcpy的声明,并用memcpy_safe调用替换对memcpy所有调用。 The new function needs to be implemented in its own translation unit, so you can call the old memcpy . 新功能需要在自己的翻译单元中实现,因此您可以调用旧的memcpy

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM