参考: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. 【消息队列】kafka是如何保证消息不被重复消费的

    一.kafka自带的消费机制 kafka有个offset的概念,当每个消息被写进去后,都有一个offset,代表他的序号,然后consumer消费该数据之后,隔一段时间,会把自己消费过的消息的offs ...

  2. 20180831xlVBA_WorkbooksCosolidate

    Sub WorkbooksConsolidate() Rem 设置求和区域为 sheet名称/单元格区域;sheet名称/单元格区域 Const Setting As String = "S ...

  3. ES7: 展开语法spread syntax:

    第一次遇到: payload = {...payload, manufacturer: state.manufacturers.filter(x => x._id === payload.man ...

  4. CF-831D Office Keys 思维题

    http://codeforces.com/contest/831/problem/D 题目大意是在一条坐标轴上,给出n个人,k把钥匙(k>=n)以及终点的坐标,所有人都可以同时运动,但不可以公 ...

  5. Elasticsearch SQL

    es sql是一个X-pack组件 ,允许对es执行类似sql的查询,可以将Elasticsearch SQL理解为一个编译器,既能理解es,又能理解sql.可以通过利用es,实施大规模实时读取和处理 ...

  6. 使用xshell远程连接

    xshell 是一个强大的安全终端模拟软件,它支持SSH1,SSH2以及microsoft windows 平台的TELNET协议.xshell通过互联网到远程主机的安全连接. xshell可以在wi ...

  7. mac下 配置homebrew 和java home

    1.terminal下输入   /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/insta ...

  8. Known Notation ZOJ - 3829 (后缀表达式,贪心)

    大意:给定后缀表达式, 每次操作可以添加一个字符, 可以交换两个字符的位置, 相邻数字可以看做一个整体也可以分开看, 求合法所需最少操作数. 数字个数一定为星号个数+1, 添加星号一定不会更优. 先判 ...

  9. python FileNotFoundError: [WinError 2] 系统找不到指定的文件。

    D:\Test\TestSWP\Scripts\python.exe D:/Test/SWP/TestSWP/chorme/chorme.pyTraceback (most recent call l ...

  10. react中使用antd Table组件滚动加载数据的实现

    废话不多说,直接上代码.一目了然. import React, { Component } from "react"; import { Table } from "an ...