不使用 = 重载赋值运算符

overloading assignment operator without using =

我在面试中被问到一个问题。

Is there a way that you can assign the value of one user-defined object to another user-defined object without using = operator.

基本上,他让我重载 class 的赋值运算符,这样重载的赋值运算符反过来就不会使用原始类型 = 运算符。

memcpy 是正确的方法吗?

提出的问题:memcpy 是正确的方法吗?不总是。

隐含的问题:重载赋值运算符而不使用 =? 使用 Copy and Swap Idiom.

我将通过解释所问问题的答案为何为否来演示隐含问题。

memcpy 执行二进制复制,而不对被复制对象中变量的性质应用任何上下文。它可能非常危险,只能用于 trivially copyable 的对象。

考虑以下情况:

struct A
{
    int buffersize;
    char * buffer;
    A(int size):buffersize(size), buffer(new char[buffersize])
    {
    }
    A(const A& source):buffersize(source.buffersize), buffer(new char[buffersize])
    {
        memcpy(buffer, source.buffer, buffersize);
    }
    ~A()
    {
        delete[] buffer;
    }
    A& operator=(A source) // Assignment via Copy and Swap Idiom
    {
        std::swap(buffersize, source.buffersize);
        std::swap(buffer, source.buffer);
    }
}

这个例子很愚蠢也很简单。任何理智的人都会使用 std::vector,但它确实实现了三法则 (What is The Rule of Three?),因此可以安全地复制而不是简单地复制。

看到复制构造函数中正在执行的工作了吗? memcpy 不会执行此操作。 memcpy 将复制 buffer 的值、地址,并为您留下指向同一个 buffer 的两个对象。如果缓冲区的共享没有尽快证明是致命的,最终两个析构函数将不得不 运行 和 buffer 将被释放两次。

注意memcpy正在用于复制内部缓冲区。缓冲区是一个普通旧数据 (POD) 数组,可以轻松复制。如果它不是平凡可复制的,则应遵循 πìντα ῥεῖ std::copy 的建议。在任何一种情况下我们都应该使用 std:::copy 以便将来更容易修改代码,但是这个例子并没有显示 memcpy.

的安全使用