#include <iostream> #include <cstdlib> using namespace std; //变长数组类 class Array{ public: Array(int len); Array(const Array &arr); //拷贝构造函数 ~Array(); public: int operator[](int i) const { return m_p[i]; } //获取元素(读取) int &operator[](int i){ return m_p[i]; } //获取元素(写入) Array & operator=(const Array &arr); //重载赋值运算符 int length() const { return m_len; } private: int m_len; int *m_p; }; Array::Array(int len): m_len(len){ m_p = (int*)calloc( len, sizeof(int) ); } Array::Array(const Array &arr){ //拷贝构造函数 this->m_len = arr.m_len; this->m_p = (int*)calloc( this->m_len, sizeof(int) ); memcpy( this->m_p, arr.m_p, m_len * sizeof(int) ); } Array::~Array(){ free(m_p); } Array &Array::operator=(const Array &arr){ //重载赋值运算符 if( this != &arr){ //判断是否是给自己赋值 this->m_len = arr.m_len; free(this->m_p); //释放原来的内存 this->m_p = (int*)calloc( this->m_len, sizeof(int) ); memcpy( this->m_p, arr.m_p, m_len * sizeof(int) ); } return *this; } //打印数组元素 void printArray(const Array &arr){ int len = arr.length(); for(int i=0; i<len; i++){ if(i == len-1){ cout<<arr[i]<<endl; }else{ cout<<arr[i]<<", "; } } } int main(){ Array arr1(10); for(int i=0; i<10; i++){ arr1[i] = i; } printArray(arr1); Array arr2(5); for(int i=0; i<5; i++){ arr2[i] = i; } printArray(arr2); arr2 = arr1; //调用operator=() printArray(arr2); arr2[3] = 234; //修改arr1的数据不会影响arr2 arr2[7] = 920; printArray(arr1); return 0; }运行结果:
去掉operator=()后,由于 m_p 指向的堆内存会被 free() 两次,所以还会导致内存错误。下面我们就来分析一下重载过的赋值运算符。
Array &
,这样不但能够避免在返回数据时调用拷贝构造函数,还能够达到连续赋值的目的。下面的语句就是连续赋值:
arr4 = arr3 = arr2 = arr1;
if( this != &arr)
语句的作用是「判断是否是给同一个对象赋值」:如果是,那就什么也不做;如果不是,那就将原有对象的所有成员变量一一赋值给新对象,并为新对象重新分配内存。下面的语句就是给同一个对象赋值:
arr1 = arr1;
arr2 = arr2;
return *this
表示返回当前对象(新对象)。const Array &
,这样不但能够避免在传参时调用拷贝构造函数,还能够同时接收 const 类型和非 const 类型的实参,这一点已经在《C++拷贝构造函数》中进行了详细讲解。Array & operator=(const Array &arr, int a = 100);
Copyright © 广州京杭网络科技有限公司 2005-2024 版权所有 粤ICP备16019765号
广州京杭网络科技有限公司 版权所有