这次分配和复制cnstr能组织得更好吗

Can this Assignment and Copy cnstr be organized better

本文关键字:更好 cnstr 分配 复制      更新时间:2023-10-16

我正在努力提高对复制构造函数和复制赋值的理解。操作人员这是我提出的的一个简单类

class Bar
{
    char* name;
    int zip;
    std::string address;
    public:
    Bar(const Bar& that)
    {
            //Copy constructor
            size_t len = strlen(that.name + 1);
            name = new char[len];
            strcpy(name, that.name);
            //Copy the zip
            this->zip = that.zip;
            //Copy the address
            this->address = that.address;
    }
    Bar& operator=(const Bar& that)
    {
        //Assignment operator
        if(this != &that)
        {
            //Copy the name
            size_t len = strlen(that.name + 1);
            name = new char[len];
            strcpy(name, that.name);
            //Copy the zip
            this->zip = that.zip;
            //Copy the address
            this->address = that.address;
        }
        return *this;
    }
};

我的问题是,由于复制构造函数和复制赋值运算符中的代码是相同的,所以将其统一为深度复制方法更有意义吗?这样,如果我添加另一个成员变量,我就不必在复制cnstr和复制赋值中添加另一行。部分有什么建议吗?

管理自己资源的"正常"做事方式有点不同:

char* cppstrdup(const char*s, int len=0);
class Bar
{
    char* name;
    int zip;
    std::string address;    
public:
    Bar(const Bar& that)
        :name(nullptr),
        zip(that->zip),
        address(that->address)
    {
        name = cppstrdup(that.name); //done here for exception safety reasons
    }
    Bar(Bar&& that) //if you have C++11 then you'll want this too
        :name(nullptr)
    {
        swap(*this,that);
    }
    ~Bar() //you forgot the destructor
    {
        delete [] name;
    }
    Bar& operator=(Bar that) //this is called copy and swap.
    { //"that" is a copy (notice, no & above), and we simply swap
        swap(*this,that);
        return *this;
    }
    friend void swap(Bar& left, Bar& right)
    {
        using std::swap;
        swap(left.name, right.name);
        swap(left.zip, right.zip);
        swap(left.address, right.address);
    }
};
//uses new instead of malloc
inline char* cppstrdup(const char* s, int len)
{
     if (s==0) return nullptr;
    if (len==0) len = strlen(s);
    char* r = new char[len+1];
    strncpy(r, len+1, s);
    r[len] = 0;
    return r;
}

这种模式的好处是,它更容易获得异常安全性,通常具有强大的异常保证。

当然,更正常的是不使用char*名称,并遵守"零规则"。在这种情况下,它变得非常不同:

class Bar
{
    std::string name;
    int zip;
    std::string address;
public:
    Bar() = default; //well, that's easy
};

检查COPY&SWAP习语。简而言之,您的逻辑进入复制构造函数和交换方法,您的赋值运算符看起来像:

Bar& operator=(const Bar& that)
{
    Bar temp(that);
    swap(*this, temp);
    return *this;
}