我目前正在编写一个创建动态分配的循环数组的程序。为此,我创建了一个复制构造函数和一个赋值运算符。
当我尝试第二次调用赋值运算符时,出现错误消息“ 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;
}
答案 0 :(得分:0)
我是否正确编写了复制构造函数和赋值运算符?
我会说,在编写赋值运算符时,您将为自己做更多的工作。
如果您已经编写了一个复制构造函数(您拥有)和一个析构函数(您没有显示,但假设您已经编写了),并且这两个函数都没有错误,那么可以实现赋值运算符简单地使用copy / swap。
通常,您应该努力在编写赋值运算符之前先编写复制构造函数和析构函数,以便可以利用编写赋值运算符的“技巧”。这是一个示例:
#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
的销毁有效)的原因。