首页 > 编程语言 >C++下标运算符详解

C++下标运算符详解

时间:2023-09-14 22:34:30浏览次数:49  
标签:const int C++ 运算符 对象 length operator 下标 Array

C++ 规定,下标运算符[ ]必须以成员函数的形式进行重载。该重载函数在类中的声明格式如下:

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

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

C++下标运算符详解_成员函数

使用第一种声明方式,[ ]不仅可以访问元素,还可以修改元素。使用第二种声明方式,[ ]只能访问而不能修改元素。在实际开发中,我们应该同时提供以上两种形式,这样做是为了适应 const 对象,因为通过 const 对象只能调用 const 成员函数,如果不提供第二种形式,那么将无法访问 const 对象的任何元素。下面我们通过一个具体的例子来演示如何重载[ ]。我们知道,有些较老的编译器不支持变长数组,例如 VC6.0、VS2010 等,这有时候会给编程带来不便,下面我们通过自定义的 Array 类来实现变长数组。

#include <iostream>
    using namespace std;
    class Array{
    public:
        Array(int length = 0);
        ~Array();
    public:
        int & operator[](int i);
        const int & operator[](int i) const;
    public:
        int length() const { return m_length; }
        void display() const;
    private:
        int m_length;  //数组长度
        int *m_p;  //指向数组内存的指针
    };
    Array::Array(int length): m_length(length){
        if(length == 0){
            m_p = NULL;
        }else{
            m_p = new int[length];
        }
    }
    Array::~Array(){
        delete[] m_p;
    }
    int& Array::operator[](int i){
        return m_p[i];
    }
    const int & Array::operator[](int i) const{
        return m_p[i];
    }
    void Array::display() const{
        for(int i = 0; i < m_length; i++){
            if(i == m_length - 1){
                cout<<m_p[i]<<endl;
            }else{
                cout<<m_p[i]<<", ";
            }
        }
    }
    int main(){
        int n;
        cin>>n;
        Array A(n);
        for(int i = 0, len = A.length(); i < len; i++){
            A[i] = i * 5;
        }
        A.display();
       
        const Array B(n);
        cout<<B[n-1]<<endl;  //访问最后一个元素
       
        return 0;
    }

运行结果:

5↙

0, 5, 10, 15, 20

33685536

重载[ ]运算符以后,表达式arr[i]会被转换为:

arr.operator[ ](i);

需要说明的是,B 是 const 对象,如果 Array 类没有提供 const 版本的operator[ ],那么第 60 行代码将报错。虽然第 60 行代码只是读取对象的数据,并没有试图修改对象,但是它调用了非 const 版本的operator[ ],编译器不管实际上有没有修改对象,只要是调用了非 const 的成员函数,编译器就认为会修改对象(至少有这种风险)。

标签:const,int,C++,运算符,对象,length,operator,下标,Array
From: https://blog.51cto.com/u_15641375/7474567

相关文章

  • 运算符完结补充
    运算符完结逻辑运算符&&||!andor反义&&:你我都对才有true||:你我有一个对就是true!:将运算结果反转true变falsefalse变true备注:用逻辑运算符进行运算是遵从短路原则,假设使用a&&b,a一旦不成立b中的内容也不会被执行,如果我们给c赋值为5,在a不成立的条件......
  • C++ STL
    Dev-C++可在工具->编译选项->代码生成/优化->代码生成->语言标准中选择“ISOC++11”或“GNUC++11”来支持C++11的新特性(蓝Dev还不支持C++14)不声明下,区间均为左闭右开区间,typename表示一个数据类型而不是C++的关键字。Containter(容器)vectorvector<t......
  • C++字符串
      1,2这个形式的字符串数组,就和普通数组一样,定义后面的大括号,里面装着每个具体的值,然后3,4直接表示出来,然后其实直接3就OK了,4可能是为了方便看。   字符串数组输入部分1.这个。。先把字符串数组定义好,然后使用cin直接输入进去2.如果想要读入包含空格键之类字符串的话......
  • C++11之智能指针(万字长文详解)
    C++11之智能指针为什么需要智能指针#include<iostream>usingnamespacestd;intdiv(){inta,b;cin>>a>>b;if(b==0)throwinvalid_argument("除0错误");returna/b;}voidFunc(){//1、如果p1这......
  • C++基础语言作用
    C++跟C语言是相关联的。页面排序:includeincludeusingnamespacestd;intmain(){...return0;}cin作为输入,类似于C语言的scanf。输入时添加>>a代表输入a值。可以接收一行内多个数据输入,不可以接收多行数据。cout作为输出,类似C语言的printf。cout默认是在一行内输出,如......
  • ros2迁移c++之package.xml、CMakeLists.txt及编译
    1、package.xml<package><!--1.根标签--> <name><!--2.包名--> <version><!--3.版本号--> <description><!--4.包描述--> <maintainer><!--5.维护者--> <......
  • c++并发编程实战-第3章 在线程间共享数据
    线程间共享数据的问题多线程之间共享数据,最大的问题便是数据竞争导致的异常问题。多个线程操作同一块资源,如果不做任何限制,那么一定会发生错误。例如:1intg_nResource=0;2voidthread_entry()3{4for(inti=0;i<10000000;++i)5g_nResource++......
  • c++ 实现 二叉树的 先序遍历,中序遍历 ,后序遍历
    遍历二叉树跟数组不同,树是一种非线性的数据结构,是由n(n>=0)个节点组成的有限集合。如果n==0,树为空树。如果n>0,树有一个特定的节点,叫做根节点(root)。 对于树这种数据结构,使用最频繁的是二叉树。每个节点最多只有2个子节点的树,叫做二叉树。二叉树中,每个节点的子节点作为根的两个子......
  • C++ 实现 快速排序
    #include<iostream>usingnamespacestd;voidquickSort(int(&)[10],int,int);intpartition(int(&)[10],int,int);voidprintArr(constint(&)[10]);voidswap(int(&)[10],int,int);intmain(){ intarr[10]={23,45,18,6,11,19,22,......
  • 用c++ 实现 二分查找 前提是先把数组排列好
    #include<iostream>usingnamespacestd;//可以递归调用的二分查找intsearch(constint(&a)[10],intstart,intend,inttarget){ //基准情况:目标值超出范围,或者start>end,说明没有找到 if(target<a[start]||target>a[end]||start>end) return-1; //取二分......