超载分配运算符无需使用=

overloading assignment operator without using =

本文关键字:分配 运算符 超载      更新时间:2023-10-16

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

是否有一种方法可以将一个用户定义对象的值分配给另一个用户定义的对象而不使用=操作器。

基本上,他要求我超载该类的分配运算符,以使超载分配运算符内置不使用原始类型=运算符。

memcpy是正确的方法吗?

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

含义的问题:超载分配运算符而无需使用=?使用副本和交换成语。

我将通过解释为什么问问题的答案是否。

来证明隐含的问题。

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,但是它确实实施了三个规则(三个规则是什么?),以便在不被琐碎的同时复制安全。

看到复制构造函数中执行的工作?这不会由memcpy执行。memcpy将复制地址buffer的值,并留下两个指向相同buffer的对象。如果缓冲区的共享并不能尽快证明致命,则最终将必须运行两个灾难,并且buffer将被释放两次。

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