第34课 数组操作符的重载
2018-01-15 14:04
344 查看
1、字符串类的兼容性
1.1、string类最大限度的考虑了C字符串的兼容性1.2、可以按照使用C字符串的方式使用string对象,如
string s = "abcdefg" ;
char c = s[i];
/******************** 用C方式使用string类 ****************/
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s = "a1b2c3d4e5";
int n = 0;
for(int i=0; i<s.length(); i++)
{ //这样是为了兼容C语言
if(isdigit(s[i]))//通过C字符串方式使用string对象(即数组)
{
n++; //计算字符串中有几个数字,isdigit()函数,判断字符型是否为数字。
}
}
cout << n << endl; //5
return 0;
}
2、类的对象如何支持数组的下标访问
2.1、数组访问是C/C++中的内置操作符2.2、数组访问符的原生意义是数组访问和指针运算
a
<----> *(a+n)指针加偏移量访问数组 <---->根据加法交换律*(n+a) <------> n[a]
/********************** 指针和数组的复习 *****************/
#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; //a[i]
}
cout << endl;
for (int i=0; i<5; i++)
{
i[a] = i; //根据加法交换律
}
cout << endl;
for(int i=0; i<5; i++)
{
//指针方式访问数组,比较不直观!而下标访问的使用,可以隐藏对指针的操作。
cout<< *(i+a)<< endl; //i[a] 等价于a[i]
}
return 0;
}
3、重载数组访问的操作符:[]
3.1、只能通过类的成员函数重载 数组名a 代表首元素的首地址类似 &a[0]。
3.2、重载函数能且仅能使用一个参数
3.3、可以定义不同参数的多个重载函数
3.4、可以隐藏对指针的操作
/**************** 重载数组访问操作符 ***************/
#include <iostream>
#include <string>
using namespace std;
class Test
{
private:
int a[5]; //没有初始化
public:
//重载数组操作符,能且只能一个参数
//返回值为引用,可以作为左值使用,即 Test t; t[1] = 2;
int& operator[](int i)
{
return a[i]; //返回变量的引用。
}
int& operator[] (const string& s) //s是一个string对象的引用
{
if(s == "1st"){
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 sizeof(a)/sizeof(*a);
}
};
/*
//通过数组的方式来访问string对象,操作后,对象里面的的一些成员方法可能不会更新,譬如string中的length()方法。
*/
int main()
{
Test t; //对象
for(int i=0; i<t.length(); i++)
{
//通过下标方式访问对象,但本质上重载操作符是个函数,即 t[i]是通过函数调用(不是数组)来访问的。类似 t.operator[](i) = i;
//赋值给函数的返回值是不合法的。
t[i] = i; //操作符[]返回的是引用,可以作为左值。给数组元素初始化。
}
for(int i=0; i<t.length(); i++)
{
cout << t[i] << endl;
}
cout << endl;
cout << "分隔符" << endl;
cout << endl;
cout << t["5th"] << endl;// 4 本质是函数调用。类似t.operator[]("5th") .
cout << t["4th"] << endl;
cout << t["3rd"] << endl;
cout << t["2nd"] << endl;
cout << t["1st"] << endl;//0
return 0;
}
数组类的改进,重载了[]数组操作符、
//IntArray.h
#ifndef _TEST_H_
#define _TEST_H_
class IntArray
{
private:
int m_length;
int* m_pointer;
IntArray(int leng);
bool construct(); //二阶构造
public:
static IntArray* NewInstance(int length);//提供创建对象的函数,二阶构造核心
~IntArray();
int length();
bool get(int index, int& value);
bool set(int index, int value);
int& operator[] (int pos);
IntArray& self();//因为该类只能在堆空间上创建对象,为了操作方便通过这里返回对象的引用,可以避开操作指针的麻烦。
};
#endif
IntArray.cpp
#include "test.h"
#include <cstdlib>
int m_length;
int* m_pointer;
IntArray::IntArray(int leng)
{
m_length = leng;
}
bool IntArray::construct() //二阶构造
{
bool ret = true;
m_pointer = new int[m_length]; //只能申请int类型的数组类 。
if(m_pointer)
{
for(int i=0; i<m_length; i++)
{
m_pointer[i] = 0; //将数组初始化为0;
}
}
else
{
delete[] m_pointer;
ret = false;
}
return ret;
}
//函数是从属于类的,直接类名调用。
IntArray* IntArray::NewInstance(int length)//提供创建对象的函数,二阶构造核心
{
IntArray* ret = new IntArray(length);//获得这个类
if(!((ret) && (ret->construct()))) //调用二阶,构造数组
{
delete ret;
ret = NULL;
}
return ret;
}
IntArray::~IntArray()
{
if(!m_pointer)
{
delete[] m_pointer;
}
}
int IntArray::length()
{
return m_length;
}
bool IntArray::get(int index, int& value)
{
bool ret = true;
if((0<=index)&&(index<m_length))
{
value = m_pointer[index];
}
else
{
ret = false;
}
return ret;
}
bool IntArray::set(int index, int value)
{
bool ret = ((0<=index)&&(index < m_length));
if(ret)
{
m_pointer[index] = value;
}
return ret;
}
int& IntArray::operator[] (int pos)
{
return m_pointer[pos];//返回引用可以做左值,重载操作符。
}
IntArray& IntArray::self()
{
return *this; //奇淫技巧,谁调用这个函数,将返回谁的引用。避免直接操作指针的麻烦。
}
main.cpp
#include <iostream>
#include <string>
#include "test.h"
using namespace std;
/**************** 数组类 ***************/
int main()
{
IntArray* ret = IntArray::NewInstance(5);
if(ret != NULL)
{//引用就是相当于在操作对象本身。
IntArray& array = ret->self();//避免了直接操作指针的麻烦。通过指针获取对象的小技巧。
cout << array.length() << endl;
array[0] = 1;//其实质是array.operator[](0) = 1;
for(int i=0; i<array.length(); i++)
{
cout << array[i] << endl;
}
}
/*
//重载的操作符:
int& IntArray::operator[](int index)
{
return m_pointer[index];
}
总结:重载数组操作符时[],注意为了能具备做左值的资格,函数应该返回引用。
*/
delete ret;
return 0;
}
4、小结
4.1、string类最大程度的兼容了C字符串的用法4.2、数组访问符的重载能够使得对象模拟数组的行为
4.3、只能通过类的成员函数重载数组访问符
4.4、重载函数能且仅能使用一个参数
相关文章推荐
- 第34课 - 数组操作符的重载
- 第34课 数组操作符的重载
- 数组操作符的重载
- 重载数组下标操作符,使用operator
- 重载数组下表操作符
- 34-数组操作符[]的重载
- 21、不一样的C++系列--数组操作符的重载
- c++操作符重载(数组类重载[]、=、==、!=操作符)
- 【c++习题】【17/5/22】重载数组下标操作符
- C++中重载数组下标访问操作符[ ] 和 赋值操作符 = ,* 和 -> 操作符和取反 !以及转化操作符bool和void*
- 读取数据到结构体数组(重载输入输出操作符)
- 重载数组下标操作符,使用operator
- 数组操作符的重载
- 第三十四课:数组操作符的重载----------狄泰软件学院
- C++运算符重载(12) - 重载数组索引操作符[]
- 数组的操作符重载
- 操作符的重载以及数组/vector对象的初始化
- c++操作符重载与友元函数 单目 双目 左移右移 ==号操作符重载 自定义数组
- 【C++深度剖析教程12】数组操作符的重载
- php中重载数组操作符