第四周 运算符重载
1.运算符重载的基本概念
2.赋值运算符的重载
3.运算符重载为友元函数
4.运算符重载实例:可变长数组类的实现
5.流插入运算符和流提取运算符的重载
6.类型转换运算符、自增自减运算符的重载
4.运算符重载实例:可变长数组类的实现
int main() { //要编写可变长整型数组类,使之能如下使用:
CArray a; //开始里的数组是空的
for( int i = 0;i < 5;++i)
a.push_back(i);
CArray a2,a3;
a2 = a;
for( int i = 0; i < a.length(); ++i )
cout << a2[i] << " " ;
a2 = a3; //a2是空的
for( int i = 0; i < a2.length(); ++i ) //a2.length()返回0
cout << a2[i] << " ";
cout << endl;
a[3] = 100;
CArray a4(a);
for( int i = 0; i < a4.length(); ++i )
cout << a4[i] << " ";
return 0;
}
程序输出结果是:
0 1 2 3 4
0 1 2 100 4
要做哪些事情?
1)a.push_back(i);->要用动态分配的内存来存放数组元素,需要一个指针成员变量,在析构函数里面释放内存
2) i < a.length();->要定义成员函数length
3)a2 = a;->要重载“=”
4)cout << a2[i] << " " ;->要重载“[ ]”
5)CArray a4(a);->要自己写复制构造函数,不能是缺省的
class CArray {
int size; //数组元素的个数
int *ptr; //指向动态分配的数组
public:
CArray(int s = 0); //构造函数,s代表数组元素的个数
CArray(CArray & a);//复制构造函数
~CArray();//析构函数
void push_back(int v); //用于在数组尾部添加一个元素v
CArray & operator=( const CArray & a);//用于数组对象间的赋值,深拷贝
int length() { return size; } //返回数组元素个数
int & CArray::operator[](int i) //返回值为 int 不行!不支持 a[i] = 4,所以得是引用
{
//用以支持根据下标访问数组元素,
// 如n = a[i] 和a[i] = 4; 这样的语句
return ptr[i];
//非引用的函数返回值不能作为左值使用
}
};
CArray::CArray(int s):size(s)
{
if( s == 0)
ptr = NULL;
else
ptr = new int[s];
}
CArray::CArray(CArray & a)
{
//如果不自己定义复制构造函数,那么程序会自动默认的复制构造函数,当执行CArray a2(a1);语句时,结果是a2的所有成员都和a1相同,那就会二者指向同一块内存,这是无法接受的。
if( !a.ptr) {
ptr = NULL;
size = 0;
return;
}
ptr = new int[a.size];
memcpy( ptr, a.ptr, sizeof(int ) * a.size);
size = a.size;
}
CArray::~CArray()
{
if( ptr)
delete [] ptr;
}
CArray & CArray::operator=( const CArray & a)
{
// 赋值号的作用是使“=” 左边对象里存放的数组,大小和内容都和右边的对象一样
if( ptr == a.ptr) // 防止a=a 这样的赋值导致出错
return * this;
if( a.ptr == NULL) { // 如果a 里面的数组是空的
if( ptr )//如果原数组非空,要先收回存储空间
delete [] ptr;
ptr = NULL;
size = 0;
return * this;
}
if( size < a.size) {// 如果原有空间不够大,需要重新分配空间
if(ptr)
delete [] ptr;
ptr = new int[a.size];
}
// 如果原有空间够大,就不用分配新的空间
memcpy( ptr,a.ptr,sizeof(int)*a.size);
size = a.size;
return * this;
} // CArray & CArray::operator=( const CArray & a)
void CArray::push_back(int v)
{
// 在数组尾部添加一个元素
if( ptr) {
int * tmpPtr = new int[size+1]; // 重新分配空间
memcpy(tmpPtr,ptr,sizeof(int)*size); // 拷贝原数组内容
delete [] ptr;
ptr = tmpPtr;
}
else // 数组本来是空的
ptr = new int[1];
ptr[size++] = v; // 加入新的数组元素
}
注意:void CArray::push_back(int v)这个函数每次执行都要重复性地申请新的空间、销毁原有空间,效率较低,可以从初始化开始,每次分配n(如32)个空间,当size达到n时才执行一次申请、销毁,其余是不需要的,这样可以提高效率。STL里面的vector就是这样的一种高效的可变长数组。
本文深入探讨了C++中运算符重载的概念与实践,特别是通过重载运算符实现了一个可变长数组类。该类支持动态增加元素、数组赋值、元素访问等功能,展示了如何通过重载'[]'、'='等运算符来增强类的功能。
234

被折叠的 条评论
为什么被折叠?



