覆盖 copy/move 赋值重载时是否需要删除当前成员数据?
Do I need to delete current member data when overriding copy/move assignment overload?
我正在为明天的期末考试学习 c++ class,我在学习时一直在想的一件事是 copy/move 赋值过载后分配给对象的数据会发生什么打电话。
假设我们有这个 class:
class linked_list {
public:
//You need to implement this part.
int num_nodes;
node * head;
linked_list() { num_nodes = 0; head = nullptr; }
~linked_list(); //dectructor
linked_list(const linked_list &other); //copy constructor
void operator=(linked_list &other); //copy assignment overload
linked_list(linked_list &&other); //move constructor
void operator=(linked_list &&other); //move assignmend overload
};
我意识到,在整个学期中,我一直在复制 in/taking 其他数据的所有权,而不用担心分配给对象中的先前数据。
void linked_list::operator=(linked_list &other) { //copy assignment overload
num_nodes = 0;
head = nullptr;
node * n = other.head;
while (n != nullptr) {
push_back(n->value);
n = n->next;
}
}
void linked_list::operator=(linked_list &&other) { //move assignment overload
num_nodes = other.num_nodes;
head = other.head;
other.head = nullptr;
}
就我这两个例子,当前(this)linked_list中所有节点的数据不会还在内存中漂浮吗?在执行我的 copying/moving 之前,我是否必须遍历整个当前链表并删除每个节点?
出于某种原因,我从其他学生和课程 material 那里了解到 class 析构函数在进入两个重载函数之前被隐式调用,因为我从未在任何地方看到任何提及关于必须先释放当前数据。
任何澄清都将非常有帮助。
谢谢,
你的担心是有道理的。是的,每次您实现赋值运算符(复制或移动或任何其他类型)时,您都负责在 copying/moving 新数据之前正确释放对象中可能存在(并由其拥有)的 "old" 数据英寸
可以粗略地将赋值运算符的功能描述为 析构函数 调用和 copy/move 构造函数 调用的组合(不要按字面意思理解:这不是实现赋值运算符的好方法)。 "old" 数据的销毁不会自动为您完成,即在调用您的赋值运算符之前没有自动隐式析构函数调用,这与您所说的从课程 material 中获得的氛围相反。您有责任手动实施 "old" 数据的销毁。
查看 Copy-And-Swap idiom 作为实现赋值运算符的一种可能的惯用方法。
当然,所有这一切仅适用于您的 class 的成员自己不处理正确的赋值语义(根据 Rule of Zero)。在您的示例中,您使用的是拥有原始指针,这意味着您有责任手动执行所需的资源管理步骤。
With the two examples that I have here, wouldn't the data of all the nodes in the current (this) linked_list still be floating around in memory?
是的。您需要确保旧数据是 re-used/delete 或以某种方式计算的。
Before doing my copying/moving, would I have to iterate through the entire current linked list and delete each node?
这是一种技巧。我会查看 copy and swap idiom,因为这在这种情况下可能会对您有所帮助。
For some reason I get the vibe from both other students and the course material that the class destructor is implicitly called before entering the two overloaded functions.
不,这不会发生。
because NOWHERE do I ever see any mention about having to free up current data first.
您绝对必须对数据采取措施,不能让它泄露。但这并不一定意味着您要直接释放它(它可能会被重新使用)。如果你使用复制和交换习惯用法,那么就会有一种基于复制对象的重用和销毁。
Any clarification would be extremely helpful.
希望有所帮助。
我正在为明天的期末考试学习 c++ class,我在学习时一直在想的一件事是 copy/move 赋值过载后分配给对象的数据会发生什么打电话。
假设我们有这个 class:
class linked_list {
public:
//You need to implement this part.
int num_nodes;
node * head;
linked_list() { num_nodes = 0; head = nullptr; }
~linked_list(); //dectructor
linked_list(const linked_list &other); //copy constructor
void operator=(linked_list &other); //copy assignment overload
linked_list(linked_list &&other); //move constructor
void operator=(linked_list &&other); //move assignmend overload
};
我意识到,在整个学期中,我一直在复制 in/taking 其他数据的所有权,而不用担心分配给对象中的先前数据。
void linked_list::operator=(linked_list &other) { //copy assignment overload
num_nodes = 0;
head = nullptr;
node * n = other.head;
while (n != nullptr) {
push_back(n->value);
n = n->next;
}
}
void linked_list::operator=(linked_list &&other) { //move assignment overload
num_nodes = other.num_nodes;
head = other.head;
other.head = nullptr;
}
就我这两个例子,当前(this)linked_list中所有节点的数据不会还在内存中漂浮吗?在执行我的 copying/moving 之前,我是否必须遍历整个当前链表并删除每个节点?
出于某种原因,我从其他学生和课程 material 那里了解到 class 析构函数在进入两个重载函数之前被隐式调用,因为我从未在任何地方看到任何提及关于必须先释放当前数据。
任何澄清都将非常有帮助。
谢谢,
你的担心是有道理的。是的,每次您实现赋值运算符(复制或移动或任何其他类型)时,您都负责在 copying/moving 新数据之前正确释放对象中可能存在(并由其拥有)的 "old" 数据英寸
可以粗略地将赋值运算符的功能描述为 析构函数 调用和 copy/move 构造函数 调用的组合(不要按字面意思理解:这不是实现赋值运算符的好方法)。 "old" 数据的销毁不会自动为您完成,即在调用您的赋值运算符之前没有自动隐式析构函数调用,这与您所说的从课程 material 中获得的氛围相反。您有责任手动实施 "old" 数据的销毁。
查看 Copy-And-Swap idiom 作为实现赋值运算符的一种可能的惯用方法。
当然,所有这一切仅适用于您的 class 的成员自己不处理正确的赋值语义(根据 Rule of Zero)。在您的示例中,您使用的是拥有原始指针,这意味着您有责任手动执行所需的资源管理步骤。
With the two examples that I have here, wouldn't the data of all the nodes in the current (this) linked_list still be floating around in memory?
是的。您需要确保旧数据是 re-used/delete 或以某种方式计算的。
Before doing my copying/moving, would I have to iterate through the entire current linked list and delete each node?
这是一种技巧。我会查看 copy and swap idiom,因为这在这种情况下可能会对您有所帮助。
For some reason I get the vibe from both other students and the course material that the class destructor is implicitly called before entering the two overloaded functions.
不,这不会发生。
because NOWHERE do I ever see any mention about having to free up current data first.
您绝对必须对数据采取措施,不能让它泄露。但这并不一定意味着您要直接释放它(它可能会被重新使用)。如果你使用复制和交换习惯用法,那么就会有一种基于复制对象的重用和销毁。
Any clarification would be extremely helpful.
希望有所帮助。