【发布时间】:2020-04-09 08:45:20
【问题描述】:
我正在为我创建的一个类编写一个复制赋值运算符,并使用以前的帖子作为指导: What is The Rule of Three?
我对这个人的解释的一个方面有点困惑。
这是他们的班级:
class person
{
char* name;
int age;
};
这是我用作参考的复制赋值运算符定义(至少提供了 2 个):
// 2. copy assignment operator
person& operator=(const person& that)
{
char* local_name = new char[strlen(that.name) + 1];
// If the above statement throws,
// the object is still in the same state as before.
// None of the following statements will throw an exception :)
strcpy(local_name, that.name);
delete[] name;
name = local_name;
age = that.age;
return *this;
}
我感到困惑的是,为什么它们包括delete[] name; 行?
这是他们提供的另一个例子:
person& operator=(const person& that)
{
if (this != &that)
{
delete[] name;
// This is a dangerous point in the flow of execution!
// We have temporarily invalidated the class invariants,
// and the next statement might throw an exception,
// leaving the object in an invalid state :(
name = new char[strlen(that.name) + 1];
strcpy(name, that.name);
age = that.age;
}
return *this;
}
我立即回避了这个,因为我不明白为什么该函数会检查 if(this != &that) 然后在似乎尚未生成的数组上运行 delete (delete[] name;)。调用赋值运算符时,是否在调用复制赋值运算符函数之前立即调用常规构造函数?因此意味着我们必须删除类构造函数生成的数组,因为它只能充满垃圾数据?
为什么我不能写:
name = that.name
或
name = new char[that.name.size()];
for (int i = 0; i < that.name.size(); i++)`
{
name[i] = that.name[i]
}
这可能是非常基本的,我应该只实现帖子的建议,但我的实际用例涉及一个包含多个成员的 structs 数组,所以我只是有点难以理解我到底需要什么去做。
我知道这里有大约 2.5 个问题。任何见解将不胜感激。
这是我第一次实现自定义复制构造函数和复制赋值运算符,我相信在我完成几次之后会看起来很容易。
提前致谢。
【问题讨论】:
-
如果新旧
name的长度相同,您可以重用name指针。但如果不是,它必须指向一个新的地方。 -
person temp(that); std::swap(temp.name, name); std::swap(temp.age, age); return *this;使用复制/交换而不是您的问题,这将是整个赋值运算符,前提是存在复制构造函数和析构函数。 -
更多关于Copy and Swap。
-
可以在
structs的数组上使用copy()和swap()吗? -
operator=在已存在的对象上运行。该对象必须是在代码中较早的某个时间点构建的,以便您可以对其进行赋值。例如。Person p; /* ... */ p = q;
标签: c++ class operator-overloading copy-assignment