C++深度解析(24)—数组操作符的重载、数组类的改进

1.字符串类的兼容性

  • string类最大限度地考虑了C字符串的兼容性,可以按照使用C字符串的方式使用string对象。
string s = "a1b2c3d4e";
int n = 0;
for(int i = 0;i < s.length();i++)
{
    if(isdigit(s[i])){
        n++;
    }
}
  • 编程实验:用C方式使用string类
#include<iostream>
#include<string> 

using namespace std;

int main() 
{
	string s = "a1b2c3d4e";
	int n = 0;
	for (int i = 0; i < s.length(); i++) 
	{
		if (isdigit(s[i])) // 用于检查十进制数字字符
		{
			n++;
		}
	}
	cout << n << endl;
	
	system("pause");
	
	return 0;
}
  • 打印结果为4

2.问题

  •  类的对象怎么支持数组的下标访问?

3.重载数组访问操作符

  • 被忽略的事实
    • 数组访问符是C/C++中的内置操作符 
    • 数组访问符的原生意义是数组访问和指针运算 

  • 指针与数组的复习
#include <iostream>
#include <string>

using  namespace std; 

int main() 
{ 
	int  a[5] = { 0 };

	for (int i = 0; i < 5; i++)
	{
		a[i] = i;
	}

	for (int  i = 0;  i < 5; i++) 
	{ 
		cout << *(a + i) << endl; // cout<<a[i]<<endl;
	} 
	
	cout  <<  endl; 
	
	for (int  i = 0;  i < 5;  i++) 
	{ 
		i[a] = i + 10;     // a[i]=i+10;
	} 
	
	for (int i = 0; i < 5; i++)
	{
		cout << *(i + a) << endl;  // cout<<a[i]<<endl;
	}

	system("pause");
	 
	return  0; 
} 
  • 运行结果

  • 数组访问操作符( [ ]
    • 只能通过类的成员函数重载 
    • 重载函数能且仅能使用—个参数 
    • 可以定义不同参数的多个重载函数 
  • 编程实验——重载数组访问操作符
#include<iostream>
#include<string>

using namespace std;

class Test 
{
	int a[5];

public:
	int& operator[](int i) 
	{                    //注意重载函数的返回值,正常int时无法位于等式左边 
		return a[i];
	}
	int& operator[](const string &s) 
	{
		if (s == "lst") 
		{
			return a[0];
		}
		else if (s == "2nd") 
		{
			return a[1];
		}
		else if (s == "3rd")
		{
			return a[2];
		}
		else if (s == "4th") 
		{
			return a[3];
		}
		else if (s == "5th") 
		{
			return a[4];
		}
		return a[0];
	}
	int length() 
	{
		return 5;
	}
};

int main() 
{
	Test t;
	
	for (int i = 0; i < t.length(); i++) 
	{
		t[i] = i;
	}
	for (int i = 0; i < t.length(); i++) 
	{
		cout << t[i] << endl;
	}
	cout << t["5th"] << endl;
	cout << t["4th"] << endl;
	cout << t["3rd"] << endl;
	cout << t["2nd"] << endl;
	cout << t["1st"] << endl;
	
	system("pause");
	
	return 0;
}
  • 运行结果

4.数组类改进

  • 重载赋值操作符
  • 重载数组操作符
  • 重载比较操作符
  • Array.h
#ifndef _ARRAY_H_
#define _ARRAY_H_

class Array
{
private:
    int mLength;
    int *mSpace;

public:
    Array(int length);
    int length();
	~Array();   // 析构函数
	int &operator[](int i); // 数组下标运算符重载
	Array &operator=(const Array &obj); // 赋值运算符重载
	bool operator==(const Array &obj);  
	bool operator!=(const Array &obj);
};

#endif
  • Array.cpp
#include <stdio.h>
#include "Array.h"

Array::Array(int length)
{
	if (length < 0)
	{
		length = 0;
	}
	
	mLength = length;
	mSpace = new int[mLength];
}

int Array::length()
{
	return mLength;
}

Array::~Array()
{
	mLength = -1;
	//printf("%08X\n",mSpace);
	delete[] mSpace;
}

int& Array::operator[](int i)  // 返回必须是引用,否则不能作为左值使用  
{
	return mSpace[i];
}

Array& Array::operator=(const Array &obj)
{
	delete[] mSpace;  // 释放自己原有的空间 

	mLength = obj.mLength;
	mSpace = new int[mLength];

	for (int i = 0; i < mLength; i++)
	{
		mSpace[i] = obj.mSpace[i];
	}

	return *this;
}

bool Array::operator==(const Array &obj)
{
	bool ret = true;

	if (mLength == obj.mLength)
	{
		for (int i = 0; i < mLength; i++)
		{
			if (mSpace[i] != obj.mSpace[i])
			{
				ret = false;
				break;
			}
		}
	}
	else
	{
		ret = false;
	}

	return ret;
}

bool Array::operator!=(const Array &obj)
{
	return !(*this == obj);
}
  • main.cpp
#include <stdio.h>
#include "Array.h"

int main()
{
	Array a1(10);  // 自动调用构造函数
	Array a2(0);
	Array a3(0);

	if (a1 != a2)
	{
		printf("a1 != a2\n");
	}
    
	for (int i = 0; i < a1.length(); i++)
	{
		a1[i] = i + 1;   // a1.operator[](i) = i + 1;
	}
    
    for(int i = 0; i < a1.length(); i++)
    {
        printf("Element %d: %d\n", i, a1[i]);
    }
    
	printf("\n");

	/*
	C++编译器会为每个类提供默认的赋值操作符
	默认的赋值操作符只是做简单的值复制
	类中存在指针成员变量时就需要重载赋值操作符
	*/
	//a2 = a1;   // 重载"="操作符  a2.operator=(a1);
	a3 = a2 = a1;  // 等价于a3=a2.operator(a1); 返回值为Array的引用,连续赋值
    
	if (a1 == a2)
	{
		printf("a1 = a2\n");
	}
	
	for(int i = 0; i < a2.length(); i++)
    {
        printf("Element %d: %d\n", i, a2[i]);
    }
    
    printf("Press any key to continue...");
    
	getchar();
    
	return 0;
}
  • 运行结果

  • C++编译器会为每个类提供默认的赋值操作符
  • 默认的赋值操作符只是做简单的值复制
  • 类中存在指针成员变量时就需要重载赋值操作符
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值