重载赋值运算符函数和复制构造函数中的错误

Error Within Overloaded Assignment Operator Function and Copy Constructor

本文关键字:错误 构造函数 复制 赋值运算符 函数 重载      更新时间:2023-10-16

我目前正在编写一个创建动态分配循环数组的程序。为此,我创建了一个复制构造函数和一个赋值运算符。

当我尝试第二次调用我的赋值运算符时,我收到一个名为"munmap_chunk((:无效指针"的错误。如果我调用它一次,则不会显示错误。我是否正确编写了复制构造函数和赋值运算符?如果需要任何信息,我很乐意提供,谢谢。

CircularDynamicArray(const CircularDynamicArray& source){
cout << "copy constructor called" << endl;
m_capacity = source.m_capacity;
m_size = source.m_size;
m_front = source.m_front;
m_rear = source.m_rear;
arr = new elmtype[source.m_capacity];
for(int i = 0; i < source.m_capacity; i++) {
arr[i] = source.arr[i];
}
}
//overloaded assignment operator
CircularDynamicArray &operator = (const CircularDynamicArray& source) {
cout << "Overloaded Assignment called" << endl; 
//check for self assignment
if (this == &source) {
return *this;
}
m_capacity = source.m_capacity;
m_size = source.m_size;
m_front = source.m_front;
m_rear = source.m_rear;    
delete[]arr;
for(int i = 0; i < source.m_capacity; i++) {
arr[i] = source.arr[i];
}
return *this;
}

我是否正确编写了复制构造函数和赋值运算符?

我会说,在编写赋值运算符时,您为自己所做的工作比必要的要多。

如果你已经编写了一个复制构造函数(你有(和一个析构函数(你没有展示,但让我们假设你做了(,并且这两个函数都没有错误,那么赋值运算符可以使用复制/交换轻松实现。

通常,在编写赋值运算符之前,应努力编写复制构造函数和析构函数,以便可以利用编写赋值运算符的"技巧"。 下面是一个示例:

#include <algorithm>
//...
CircularDynamicArray &operator=(const CircularDynamicArray& source) 
{
if (this != &source) 
{
CircularDynamicArray temp(source);    // Create a copy of what we want
// get the temp's innards, and give temp our stuff
std::swap(temp.m_capacity, m_capacity);
std::swap(temp.m_size, m_size);
std::swap(temp.m_front, m_front);
std::swap(temp.m_rear, m_rear);
std::swap(temp.arr, arr);
}  // goodbye temp
return *this; 
}

没有分配内存,没有delete[]调用,你甚至不需要检查自我分配(但无论如何都要这样做,为了提高效率(。 以上也是异常安全的。 分配操作员工作所需的一切,基本上完美无缺。

请注意,您需要交换所有成员变量 - 不要忘记任何变量,因为这会导致它无法正常工作。

所做的只是制作传入对象的副本,并将当前对象的内脏this与副本交换。 然后副本会随着您的旧信息而消失。 这就是为什么你需要一个工作复制构造函数(用于source的初始复制工作(和一个工作析构函数(以便temp的销毁工作(。