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++编译器会为每个类提供默认的赋值操作符
- 默认的赋值操作符只是做简单的值复制
- 类中存在指针成员变量时就需要重载赋值操作符