1,本文讲述数组操作符重载,上篇博文的字符串类 string 确实强大,但 string 类  对象还具备 C 方式字符串的灵活性吗?还能直接访问单个字符吗?

1,C 方式字符串灵活性是指能够通过数组访问操作符方便的访问字符串中的单个字符;

2,字符串类的兼容性:

1,string 类最大限度的考虑了 C 字符串的兼容性;

2,可以按照使用 C 字符串的方式使用 string 对象;

3,代码示例:

 string s = "a1b2c3d4e";
int n = ; for(int i=; i<s.length(); i++)
{
if( isdigit(s[i]) )
{
n++;
}
}

3,用 C 方式使用 string 类编程实验:

1,main.cpp 文件:

 #include <iostream>
#include <string> using namespace std; int main()
{
string s = "a1b2c3d4e";
int n = ; for(int i = ; i<s.length(); i++)
{
if( isdigit(s[i]) )
{
n++;
}
} cout << n << endl; return ;
}

2,输出结果:

4

3,在任意的 C++ 编译器中都支持数组访问的方式来使用字符串对象;

4,问题:

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

1,C++ 编译器并不支持将数组访问操作符和任意的类对象一起使用;

5,重载数组访问操作符:

1,数组访问符是 C/C++ 中的内置操作符;

1,数组访问操作符地位和 “+”、“-”、“*”、“/”、“==”、“=”     等内置操作符地位一致;

2,是操作符、地位同上,意味着可以重载;

2,数组访问符的原生意义是数组访问和指针运算;

1,a[n] <==> *(a + n) <==> *(n + a) <==> n[a];

1,指针和最终偏移地址相加,然后取元素;

2,加法交换律;

2,访问数组中的元素深层次的意义就是指针运算,算偏移量;

6,指针与数组的复习实例分析:

1,main.cpp 文件:

 #include <iostream>
#include <string> using namespace std; int main()
{
int a[] = {}; for(int i=; i<; i++)
{
a[i] = i;
} for(int i=; i<; i++)
{
cout << *(a + i) << endl; // ==> cout << a[i] << endl;
} cout << endl; for(int i=; i<; i++)
{
i[a] = i + ; // ==> a[i] = i + 10;
} for(int i=; i<; i++)
{
cout << *(i + a) << endl; // cout << a[i] << endl;
} return ;
}

2,输出结果:


2,结论:

1,数组访问操作符原生语义是访问数组中的某个元素,深层次的意义是算地址的偏移量;

7,重载数组访问操作符:

1,数组访问操作符([]):

1,只能通过类的成员函数重载;

2,重载函数能且仅能使用一个参数;

1,参数可以是不同的类型;

3,可以定义不同参数的多个重载函数;

8,重载数组访问操作符编程实验:

1,main.cpp 文件:

 #include <iostream>
#include <string> using namespace std; class Test
{
int a[]; // 被模拟的数组;
public:
int& operator [] (int i) // 能且仅能重载一个参数;引用是为了可以当做左值,因为不引用则直接是函数调用的返回值,它是不能当做左值使用的;
{
return a[i]; // 这里返回的不是局部变量,所以可以返回引用,且引用能够返回位置;
} /* 通过字符串来访问数组 */
int& operator [] (const string& s) // 定义多个重载函数;引用是为了可以当做左值;
{
if( s == "1st" )
{
return a[];
}
else if( s == "2nd" )
{
return a[];
}
else if( s == "3rd" )
{
return a[];
}
else if( s == "4th" )
{
return a[];
}
else if( s == "5th" )
{
return a[];
} return a[];
} int length()
{
return ;
}
}; int main()
{
Test t; for(int i=; i<t.length(); i++)
{
t[i] = i;
} for(int i=; 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; return ;
}

2,结论:

  1,在以后工作中要学习 C++ 后续语言如 C#、D 等语言时,会发现确实可     以将字符串作为下标来访问一个数组,它就是应用了操作符重载来实现的;

9,数组类的完善编程实验:

1,IntArray.h 文件:

 #ifndef _INTARRAY_H_
#define _INTARRAY_H_ class IntArray
{
private:
int m_length;
int* m_pointer; IntArray(int len);
IntArray(const IntArray& obj);
bool construct();
public:
static IntArray* NewInstance(int length);
int length();
bool get(int index, int& value);
bool set(int index ,int value);
int& operator [] (int index); // 数组访问操作符重载;
IntArray& self(); // 返回自身,为了不使用指针;
~IntArray();
}; #endif

 2,IntArray.cpp 文件:

 #include "IntArray.h"

 IntArray::IntArray(int len)
{
m_length = len;
} bool IntArray::construct()
{
bool ret = true; m_pointer = new int[m_length]; if( m_pointer )
{
for(int i=; i<m_length; i++)
{
m_pointer[i] = ;
}
}
else
{
ret = false;
} return ret;
} IntArray* IntArray::NewInstance(int length)
{
IntArray* ret = new IntArray(length); if( !(ret && ret->construct()) )
{
delete ret;
ret = ;
} return ret;
} int IntArray::length()
{
return m_length;
} bool IntArray::get(int index, int& value)
{
bool ret = ( <= index) && (index < length()); if( ret )
{
value = m_pointer[index];
} return ret;
} bool IntArray::set(int index, int value)
{
bool ret = ( <= index) && (index < length()); if( ret )
{
m_pointer[index] = value;
} return ret;
} int& IntArray::operator [] (int index) // 数组访问操作符重载实现;
{
return m_pointer[index];
} IntArray& IntArray::self() // 返回数组指针的引用;
{
return *this;
} IntArray::~IntArray()
{
delete[]m_pointer;
}

 3,main.cpp 文件:

 #include <iostream>
#include <string>
#include "IntArray.h" using namespace std; int main()
{
IntArray* a = IntArray::NewInstance(); // 通过智能指针对象代替这里的指针; if( a != NULL )
{
IntArray& array = a->self();//堆空间创建的对象,没有别名, 这里给它起一个别名; cout << "array.length() = " << array.length() << endl; array[] = ; for(int i=; i<array.length(); i++)
{
cout << array[i] << endl;
}
} delete a; return ;
}

10,小结:

1,string 类最大程度的兼容了 C 字符串的用法;

2,数组访问符的重载能够使得对象模拟数组的行为;

3,只能通过类的成员函数重载数组访问操作符;

4,重载函数能且仅能使用一个参数;

C++中的数组操作符重载的更多相关文章

  1. C#中如何利用操作符重载和转换操作符

    操作符重载 有的编程语言允许一个类型定义操作符应该如何操作类型的实例,比如string类型和int类型都重载了(==)和(+)等操作符,当编译器发现两个int类型的实例使用+操作符的时候,编译器会生成 ...

  2. C#中如何利用操作符重载和转换操作符 (转载)

    操作符重载 有的编程语言允许一个类型定义操作符应该如何操作类型的实例,比如string类型和int类型都重载了(==)和(+)等操作符,当编译器发现两个int类型的实例使用+操作符的时候,编译器会生成 ...

  3. C++ 数组操作符重载、函数对象分析、赋值操作符

    string类型访问单个字符 #include <iostream> #include <string> #include <sstream> using name ...

  4. C++中的赋值操作符重载和拷贝构造函数

    1,关于赋值的疑问: 1,什么时候需要重载赋值操作符? 2,编译器是否提供默认的赋值操作符? 2,关于赋值的疑问: 1,编译器为每个类默认重载了赋值操作符: 1,意味着同类型的类对象可以相互赋值: 2 ...

  5. c/c++ 重载 数组 操作符[] operator[ is ambiguous, as 0 also mean a null pointer of const char* type.

    // Note: //int x = a[0].GetInt(); // Error: operator[ is ambiguous, as 0 also mean a null pointer of ...

  6. C++基础学习笔记----第十三课(操作符重载-下)

    本节主要讲使用成员函数重载操作符,包括[],=,(),->四种操作符的重载以及&&和||的问题. 类的成员函数进行操作符重载 基本概念 类的成员函数也可以进行操作符的重载.类的普 ...

  7. 5.7 C++函数调用操作符重载

    参考:http://www.weixueyuan.net/view/6385.html 总结: 需要以类成员函数的形式对函数调用操作符“()”进行重载. 只有常成员函数才能处理常对象,故我们依然在类中 ...

  8. (二) operator、explicit与implicit 操作符重载

      有的编程语言允许一个类型定义操作符应该如何操作类型的实例,比如string类型和int类型都重载了(==)和(+)等操作符,当编译器发现两个int类型的实例使用+操作符的时候,编译器会生成把两个整 ...

  9. Kotlin操作符重载:把标准操作加入到任何类中(KAD 17)

    作者:Antonio Leiva 时间:Mar 21, 2017 原文链接:https://antonioleiva.com/operator-overload-kotlin/ 就像其他每种语言一样, ...

随机推荐

  1. percona-toolkit 3.0.13 简单安装记录

    percona-toolkit 3.0.13 简单安装记录 环境:centos6.x mysql:8.0.17 yum -y install perl-DBIyum -y install perl-D ...

  2. haproxy教程

    一.haproxy简介 HAProxy is a free, very fast and reliable solution offering high availability, load bala ...

  3. JS定时循环

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  4. LTM加速优化特性

    TCP Express TCP Express 是 LTM 产品的一项重要特性. 借助 TCP Express,LTM 可分别为客户机端和服务器端创建独立的连接.这样一来,LTM 可以针对客户机连接和 ...

  5. [luogu]P3959 宝藏[NOIP][状态压缩DP]

    [luogu]P3959 宝藏[TREASURE] 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的 ...

  6. Vue.use源码分析(转)+如何封装一个组件

    封装一个组件:https://www.jianshu.com/p/89a05706917a 我想有过vue开发经验的,对于vue.use并不陌生.当使用vue-resource或vue-router等 ...

  7. sqli-labs(22)

    接下里我们进入第二二关 好像和第21关一样 cookie的base64加密注入 闭合变成了双引号而已 0X01 构造语句进行尝试 " union select 1,2,3# IiB1bmlv ...

  8. java中的过滤器 --Filter

    package filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.Filter ...

  9. mongoose 创建自增字段方法

    first: create counter collection in mongodb:> db.counters.insert({_id:"entityId",seq:0} ...

  10. CentOS7修改计算机名!

    https://www.cnblogs.com/acgpiano/p/4170546.html sudo hostnamectl set-hostname <host-name>