c++ - 覆盖复制/move 分配重载时是否需要删除当前成员数据?

标签 c++ copy overloading move

我正在学习 C++ 类(class)的期末考试,我在学习时一直在思考的一件事是在调用复制/move 分配重载后分配给对象的数据会发生什么。

假设我们有这个类:

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

};

我意识到,在整个学期中,我一直只是复制其他数据/取得其他数据的所有权,而从来没有担心分配给对象中的先前数据。

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;
}

用我这里的两个例子,当前(这个)linked_list 中所有节点的数据不会仍然在内存中 float 吗?在进行复制/move 之前,我是否必须遍历整个当前链表并删除每个节点?

出于某种原因,我从其他学生和类(class)资料中了解到,在进入两个重载函数之前隐式调用了类析构函数,因为我从未在任何地方看到任何关于必须首先释放当前数据的提及。

任何澄清都会非常有帮助。

谢谢,

最佳答案

您的担心是有道理的。是的,每次您实现赋值运算符(复制或 move 或任何其他类型)时,您有责任在复制/move 新数据之前正确释放对象中可能存在(并由其拥有)的“旧”数据。

可以粗略地将赋值运算符的功能描述为 析构函数 调用和 复制/move 构造函数 调用的组合(不要按字面意思理解:这不是一种实现赋值运算符的好方法)。 “旧”数据的销毁不会自动为您完成,即在调用您的赋值运算符之前没有自动隐式析构函数调用,这与您说的从类(class) Material 中获得的氛围相反。您有责任手动销毁“旧”数据。

看看Copy-And-Swap idiom作为实现赋值运算符的一种可能的惯用方式。

当然,所有这一切仅适用于您的类(class)成员自己不处理正确的赋值语义(根据 Rule of Zero )。在您的示例中,您使用的是拥有原始指针,这意味着您有责任手动执行所需的资源管理步骤。

关于c++ - 覆盖复制/move 分配重载时是否需要删除当前成员数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47764011/

相关文章:

c++ - 使用QT进程使用命令行从笔记本电脑获取传感器信息

c++ - 将重载函数指针作为参数传递给重载模板函数

git - 将文件从一个存储库的特定提交/哈希复制到另一个(不相关)存储库

haskell - 无法理解 Haskell 的类型系统

java - 从子类的子类访问父成员

c++ - 将文件读入 char 数组,然后计算 strlen 卡在 C++ 中

r - 修改时复制;运行此代码时会发生什么? x <- 列表(1 :10); x[[2]] <- x

从表单中的密码字段复制

c++ - 我可以重载模板变量吗?

c++ - 运算符重载说明