参考:http://www.weixueyuan.net/view/6384.html

总结:

  下标操作符是必须要以类的成员函数的形式进行重载的。其在类中的声明格式如下:
      返回类型 & operator[] (参数)
  或
      const 返回类型 & operator[] (参数) const    ,  后面的 const可使两函数是不同的函数,编译器可以分辨出来。

  如果使用第一种声明方式,操作符重载函数不仅可以访问对象,同时还可以修改对象。如果使用第二种声明方式,则操作符重载函数只能访问而不能修改对象。如语句“arr[5] = 7;”语句是无效的,

  非const成员函数不能处理const对象,这也是第二种的应用场景之一。

---------------------------

在前面已经提到下标操作符是必须要以类的成员函数的形式进行重载的。其在类中的声明格式如下:
    返回类型 & operator[] (参数)

    const 返回类型 & operator[] (参数)

如果使用第一种声明方式,操作符重载函数不仅可以访问对象,同时还可以修改对象。如果使用第二种声明方式,则操作符重载函数只能访问而不能修改对象。

在我们访问数组时,通过下标去访问数组中的元素并不具有检查边界溢出功能,我们可以重载下标操作符使之具有相应的功能。

例1:

#include<iostream>
#include<string>
using namespace std; class Array
{
public:
Array(){length = ; num = NULL;};
Array(int n);
int & operator[]( int );
const int & operator[]( int )const;
int getlength() const {return length;}
private:
int length;
int * num;
}; Array::Array(int n)
{
try
{
num = new int[n];
}
catch(bad_alloc)
{
cerr<<"allocate storage failure!"<<endl;
throw;
}
length = n;
} int& Array::operator[](int i)
{
if(i < || i >= length)
throw string("out of bounds");
return num[i];
} const int & Array::operator[](int i) const
{
if(i < || i >= length)
throw string("out of bounds");
return num[i];
} int main()
{
Array A();
int i;
try
{
for(i = ; i < A.getlength(); i++)
A[i] = i;
for(i = ;i < ; i++ )
cout<< A[i] <<endl;
}
catch(string s)
{
cerr<< s <<", i = "<< i <<endl;
} return ;
}

本例中定义了一个Array类,表示的是一个整形数组,在类中我们重载了下标操作符,使之具备检测下标溢出的功能。在类中为了方便我们使用了string类,这个类将在后面会进行详细介绍,在这里可以将其对象理解为一个字符串。在本例中重载下标操作符,我们提供了两个版本的重载下标操作符函数:
    int & operator[]( int );
    const int & operator[]( int )const;

需要注意的是第一个下标操作符重载函数最后面不带有const,加上const意味着该成员函数是常成员函数,如果第一个函数后面也加上了const,则两个函数仅有返回值不相同,这个不足以用于区分函数,编译器会提示语法错误。这两种版本的下标操作符重载函数其实很好理解,一个是可以修改类对象,下面一个则只可以访问对象而不能修改对象。对于上面一种下标操作符重载函数的声明,以下两个语句都是有效的:
    arr[5] = 7;
    int var = arr[3];

换言之,我们既可以访问类对象,同时又能修改类对象。“arr[5]”其实可以理解为:
    arr.operator[]( 5 )

而对于下面一种下标操作符重载函数,我们不能修改对象,也就是说语句“arr[5] = 7;”语句是无效的,但是它依然可以用于访问对象,因此“int var = arr[3];”语句仍然有效。

我们再来看一下下标操作符重载函数的定义,在函数体内部,先进行下标越界检测,如果出现越界则抛出异常,否则就返回下标 i 所对应的数据。这两种版本的下标操作符重载函数的函数定义都是如此。

我们来看一下程序输出结果:
    0
    1
    2
    3
    4
    out of bounds, i = 5

在例1中即使我们没有定义const版本的,上面的例子也是可以正确运行的,但是非const成员函数不能处理const对象,因此通常我们在设计程序时,会同时提供两种版本的操作符重载函数。在例1中如果我们增添下面一个display顶层函数,用于打印对象数组中的所有元素。

void display(const Array & A)
{
for(int i=; i < A.getlength(); i++)
cout<< A[i] <<endl;
}

此时如果我们在例1中没有定义const版本的下标操作符重载函数,则例1将会出现语法错误而无法编译通过的。

5.6 C++重载下标操作符的更多相关文章

  1. 【c++习题】【17/5/22】重载数组下标操作符

    一.写出程序运行结果 1#include <iostream > using namespace std; int a[10]={1,2, 3, 4, 5, 6, 7, 8, 9, 10} ...

  2. C++ 之 重载赋值操作符

    Widget 类中,定义了一个 Bitmap 类型的私有数据成员 -- pb 指针 class Bitmap { ... }; class Widget { private: Bitmap *pb; ...

  3. C++中复制构造函数与重载赋值操作符总结

    前言 这篇文章将对C++中复制构造函数和重载赋值操作符进行总结,包括以下内容: 1.复制构造函数和重载赋值操作符的定义: 2.复制构造函数和重载赋值操作符的调用时机: 3.复制构造函数和重载赋值操作符 ...

  4. C++中复制构造函数与重载赋值操作符

    我们都知道,在C++中建立一个类,这个类中肯定会包括构造函数.析构函数.复制构造函数和重载赋值操作:即使在你没有明确定义的情况下,编译器也会给你生成这样的四个函数.例如以下类:   class CTe ...

  5. 5.9 C++重载转型操作符

    参考:http://www.weixueyuan.net/view/6387.html 注意: 转型构造函数可以将其它类型的参数转换为类类型,如果我们要进行相反的转换过程,将类类型转换为其它数据类型, ...

  6. 5.5 C++重载赋值操作符

    参考:http://www.weixueyuan.net/view/6383.html 总结: 重载赋值操作符同重载类的是拷贝构造函数的原因是一样,将一个对象拷贝给另一个对象,同时当类中存在指针类型的 ...

  7. 【c++】c++中重载输出操作符,为什么要返回引用

    针对:ostream & operator <<(ostream & os, const ClassType &object) 说明几点: 1.第一个形参为对ost ...

  8. Effective C++(10) 重载赋值操作符时,返回该对象的引用(retrun *this)

    问题聚焦: 这个准则比较简短,但是往往就是这种细节的地方,可以提高你的代码质量. 细节决定成败,让我们一起学习这条重载赋值操作符时需要遵守的准则吧. 还是以一个例子开始: Demo // 连锁赋值 x ...

  9. C++ 重载操作符- 02 重载输入输出操作符

    重载输入输出操作符 本篇博客主要介绍两个操作符重载.一个是 <<(输出操作符).一个是 >> (输入操作符) 现在就使用实例来学习:如何重载输入和输出操作符. #include ...

随机推荐

  1. JavaScript 第九章总结

    Handing events 前言 这一章节主要讲了关于 events 的内容,讲了 event 的定义,以及如何用 code 来 react to events.同时,也说明了 JavaScript ...

  2. Getting started with Processing 第六章总结

    平移,旋转和缩放 前言 在这一章节中,平移.旋转和缩放都是以原点为基准的.并且是通过控制坐标系原点的位置来达到图元平移,旋转.缩放的视觉效果.作者在文中的原话是:另一种在屏幕上改变位置和移动物体的技术 ...

  3. CentOS上安装seafile

    一.安装python2.7.14(CentOS7上python默认版本是Python 2.7.5 ,不需要安装)1.安装依赖包[root@web01 ~]# yum -y install zlib z ...

  4. hadoop挂载多硬盘,ZZ-- multiple disks per node

    hadoop挂载多硬盘 ...multiple disks per node  multiple disks per node Read more at: http://www.queryhome.c ...

  5. JDK常用工具

    JDK的命令行工具 jps 查看正在使用的jvm机器进程号. 常用命令,-l显示正在运行的jar包或者软件(基于jvm),-v显示当前进程详细的jvm参数 jps -l jps -v javap 反汇 ...

  6. apicloud 按返回键

    api.addEventListener({ name: 'keyback' }, function(ret, err) { //调取index.html暴露的方法 api.execScript({ ...

  7. Entertainment Box(可多执行的区间问题)

    本题出自: Nordic Collegiate Programming Contest 2015​ Ada, Bertrand and Charles often argue over which T ...

  8. TeamViewer一直显示“未就绪,请检查您的连接”什么原因?

    一.错误 错误:未就绪,请检查您的连接 二.问题原因 1.网络连接有问题 很多用户在点击启动TeamViewer的时候,在下方看到显示未连接状态.这种情况可能是软件自身问题,重启一下或重新下载安装包安 ...

  9. spring boot(二十)使用spring-boot-admin对服务进行监控

    上一篇文章<springboot(十九):使用Spring Boot Actuator监控应用>介绍了Spring Boot Actuator的使用,Spring Boot Actuato ...

  10. tomcat8.5 优化

    第一步:配置user登录tomcat 参考:https://www.cnblogs.com/kevincaptain/p/10370794.html 第二步:性能优化 2.1tomcat的运行模式有3 ...