这个Assignment和Copy cnstr可以更好地组织

时间:2014-04-18 20:08:56

标签: c++

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

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和复制分配。部分 ?有什么建议吗?

2 个答案:

答案 0 :(得分:2)

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

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*名称,并遵守"零规则" isntead。在这种情况下,它变得非常不同:

class Bar
{
    std::string name;
    int zip;
    std::string address;

public:
    Bar() = default; //well, that's easy
};

答案 1 :(得分:0)

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

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