Nykakin
Nykakin

Reputation: 8747

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:

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:

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:

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?

Upvotes: 8

Views: 645

Answers (2)

user877329
user877329

Reputation: 6200

This is not bullet-proof but you can implement your own memcpy_safe that behaves similarly but accepts something else than 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. The new function needs to be implemented in its own translation unit, so you can call the old memcpy.

Upvotes: 0

R Sahu
R Sahu

Reputation: 206607

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

The simple answer is "No".

Upvotes: 10

Related Questions