我正在努力提高对复制构造函数和复制赋值的理解。操作者 这是一个我提出的简单课程
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和复制分配。部分 ?有什么建议吗?
答案 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;
}