不使用 = 的重载赋值运算符

overloading assignment operator without using =

提问人:Sid 提问时间:3/9/2019 最后编辑:Remy LebeauSid 更新时间:3/9/2019 访问量:334

问:

在一次采访中,我被问到一个问题。

有没有办法在不使用 = 运算符的情况下将一个用户定义对象的值分配给另一个用户定义对象。

基本上,他要求我重载类的赋值运算符,以便重载赋值运算符反过来不会使用基元类型 = 运算符。

正确的方法吗?memcpy

C++ C++11 重载 赋值运算符

评论

0赞 πάντα ῥεῖ 3/9/2019
“memcpy是正确的方法吗?”对于 c++,这种情况很少发生。 似乎是一种更理智的方法。std::copy()

答:

3赞 user4581301 3/9/2019 #1

问题:memcpy是正确的方法吗?并非总是如此。

隐含的问题:不使用 =?使用 Copy and Swap 惯用语

我将通过解释为什么被问问题的答案是否定的来证明隐含的问题。

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

请考虑以下情况:

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

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

注意 IS 用于复制内部缓冲区。缓冲区是可简单复制的普通旧数据 (POD) 数组。如果它不是微不足道的可复制的,则应遵循 πάντα ῥεῖ 的 std::copy 建议。无论哪种情况,我们都应该使用,以便将来更容易修改代码,但该示例并未显示 .memcpystd:::copymemcpy