我可以防止对象被 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
.
使用私有复制构造函数和赋值运算符 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
.