C++中的数组操作符重载
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++中的数组操作符重载的更多相关文章
- C#中如何利用操作符重载和转换操作符
操作符重载 有的编程语言允许一个类型定义操作符应该如何操作类型的实例,比如string类型和int类型都重载了(==)和(+)等操作符,当编译器发现两个int类型的实例使用+操作符的时候,编译器会生成 ...
- C#中如何利用操作符重载和转换操作符 (转载)
操作符重载 有的编程语言允许一个类型定义操作符应该如何操作类型的实例,比如string类型和int类型都重载了(==)和(+)等操作符,当编译器发现两个int类型的实例使用+操作符的时候,编译器会生成 ...
- C++ 数组操作符重载、函数对象分析、赋值操作符
string类型访问单个字符 #include <iostream> #include <string> #include <sstream> using name ...
- C++中的赋值操作符重载和拷贝构造函数
1,关于赋值的疑问: 1,什么时候需要重载赋值操作符? 2,编译器是否提供默认的赋值操作符? 2,关于赋值的疑问: 1,编译器为每个类默认重载了赋值操作符: 1,意味着同类型的类对象可以相互赋值: 2 ...
- 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 ...
- C++基础学习笔记----第十三课(操作符重载-下)
本节主要讲使用成员函数重载操作符,包括[],=,(),->四种操作符的重载以及&&和||的问题. 类的成员函数进行操作符重载 基本概念 类的成员函数也可以进行操作符的重载.类的普 ...
- 5.7 C++函数调用操作符重载
参考:http://www.weixueyuan.net/view/6385.html 总结: 需要以类成员函数的形式对函数调用操作符“()”进行重载. 只有常成员函数才能处理常对象,故我们依然在类中 ...
- (二) operator、explicit与implicit 操作符重载
有的编程语言允许一个类型定义操作符应该如何操作类型的实例,比如string类型和int类型都重载了(==)和(+)等操作符,当编译器发现两个int类型的实例使用+操作符的时候,编译器会生成把两个整 ...
- Kotlin操作符重载:把标准操作加入到任何类中(KAD 17)
作者:Antonio Leiva 时间:Mar 21, 2017 原文链接:https://antonioleiva.com/operator-overload-kotlin/ 就像其他每种语言一样, ...
随机推荐
- asp.net+批量下载附件
asp.net 下载文件几种方式 protected void Button1_Click(object sender, EventArgs e) { /* 微软为Response对象提供了一个新的方 ...
- 模型层ORM操作
一.ORM操作 1.关键性字段及参数 DateField 年月日 DateTimeField 年月日时分秒 auto_now: 每次操作改数据都会自动更新时间 auto_now_add: 新增数据的时 ...
- Mac item2常用快捷键
记录一下iterm 2 快捷键,用于备忘! 标签 新建标签:command + t 关闭标签:command + w 切换标签:command + 数字 command + 左右方向键 切换全屏:co ...
- 2-gitblit添加项目,项目成员
创建代码仓库,如下图所示, 然后填个项目的名称和描述即可点击保存. 用户也是,还是相同的位置,点击用户,而不是用户中心,创建用户也是填写用户名称和简称,最后对在旁边有个用户的权限,选择相应的代码仓库即 ...
- [CSP-S模拟测试]:数列(数学)
题目传送门(内部题95) 输入格式 第一行三个整数$n,a,b$,第二行$n$个整数$x_1\sim x_n$表示数列. 输出格式 一行一个整数表示答案.无解输出$-1$. 样例 样例输入:2 2 3 ...
- HTTP请求方式之POST和GET的区别
GET请求方式: 如果我们的网页收集到的用户数据,他规定了,此网页用户数据用GET的请求方式去处理的话,我们会发现,比如百度,就是一个很经典的GET请求方式 当我们在百度搜索上输入一个‘java’,点 ...
- bash脚本计算某程序的进程数
脚本里面有时候需要判断某个程序是否启动,以及有几个进程下面用nginx来做实例 显示所有的nignx进程 ps -ef|grep nginx |grep -v grep 其中grep -v grep表 ...
- rtmp协议分析
最近需要做一个rtmp服务器,着手分析一下rtmp协议,开干. rtmp握手 这个推荐一篇文章讲解得比较透彻http://blog.sina.com.cn/s/blog_676e11660102v8b ...
- linux交叉编译Windows版本的ffmpeg
主要参考http://www.cnblogs.com/haibindev/archive/2011/12/01/2270126.html 在我的机器上编译libfaac的时候 出现问题了 输出如下 . ...
- HTTP缓存初识
一.HTTP缓存 1.强制缓存 2.协商缓存 静态资源 动态资源 二.总结 参考: http://muchstudy.com/2016/08/18/HTTP%E7%BC%93%E5%AD%98%E8% ...