• 24 数组操作符的重载


    1 问题

    • string 类对象还具备 C 语言方式字符串的灵活性么?还能直接访问单个字符么?
      • 不可以直接访问单个字符,但可以通过重载数组访问操作符来进行访问

    2 字符串类的兼容性

    • string 类最大限度地考虑了 C 字符串的兼容性

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

    • 示例1:用 C 方式使用 string

      • Demo

        #include <iostream>
        #include <string>
        
        using namespace std;
        
        int main()
        {
            string s = "a1b2c3d4e";
            int n = 0;
                
            for(int i = 0; i < s.length(); i++)
            {
                if( isdigit(s[i]) ) {
                    n++;
                }
            }
            
            cout << n << endl;  // 4
            
            return 0;
        }
        
    • 【问题】类的对象怎么支持数组下标访问的?

      • 重载数组访问操作符

    3 重载数组访问操作符

    • 数组访问符是 C/C++ 中的内置操作符

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

      a[n] <=> *(a + n) <=> *(n + a) <=> n[a]

    • 示例2:指针与数组的复习

      • Demo

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

        0
        1
        2
        3
        4
        
        10
        11
        12
        13
        14
        
    • 数组访问操作符([]

      • 只能通过类的成员函数重载
      • 重载函数能且仅能使用一个参数
      • 可以定义不同参数的多个重载函数
    • 示例3:重载数组访问操作符

      • Demo

        #include <iostream>
        #include <string>
        
        using namespace std;
        
        class Test
        {
            int a[5];
        public:
            // 有且仅有一个参数,这里返回值得是引用,否则不能作为左值出现在赋值符号的左边
            int& operator [] (int i) {
                return a[i];
            }
            
            // 多个重载函数
            int& operator [] (const string& s) {
                if( s == "1st" ) {
                    return a[0];
                }
                else if( s == "2nd" ) {
                    return a[1];
                }
                else if( s == "3rd" ) {
                    return a[2];
                }
                else if( s == "4th" ) {
                    return a[3];
                }
                else if( s == "5th" ) {
                    return a[4];
                }
                
                return a[0];
            }
            
            int length() {
                return 5;
            }
        };
        
        int main()
        {
            Test t;
            
            for(int i = 0; i < t.length(); i++) {
                // 函数返回引用可以作为左值使用
                t[i] = i;
            }
            
            for(int i = 0; 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 0;
        }
        
      • 编译运行

        0
        1
        2
        3
        4
        4
        3
        2
        1
        0
        
    • 数组类 IntArray 的完善

      • Demo

        //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
        
        
        //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=0; i<m_length; i++)
                {
                    m_pointer[i] = 0;
                }
            }
            else
            {
                ret = false;
            }
            
            return ret;
        }
        
        IntArray* IntArray::NewInstance(int length) 
        {
            IntArray* ret = new IntArray(length);
            
            if( !(ret && ret->construct()) ) 
            {
                delete ret;
                ret = 0;
            }
                
            return ret;
        }
        
        int IntArray::length()
        {
            return m_length;
        }
        
        bool IntArray::get(int index, int& value)
        {
            bool ret = (0 <= index) && (index < length());
            
            if( ret )
            {
                value = m_pointer[index];
            }
            
            return ret;
        }
        
        bool IntArray::set(int index, int value)
        {
            bool ret = (0 <= 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;
        }
        
        
      • 使用

        #include <iostream>
        #include <string>
        #include "IntArray.h"
        
        using namespace std;
        
        int main()
        {
            IntArray* a = IntArray::NewInstance(5);    
            
            if( a != NULL )
            {
                IntArray& array = a->self();
                
                cout << "array.length() = " << array.length() << endl;
            
                array[0] = 1;
                
                for(int i = 0; i < array.length(); i++)
                {  
                    cout << array[i] << endl;
                }
            }
            
            delete a;
            
            return 0;
        }
        
      • 编译运行

        array.length() = 5
        1
        0
        0
        0
        0
        
  • 相关阅读:
    视频笔记
    【LeetCode】给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度
    getopt函数用法
    一些常用的算法库
    c语言结构体
    C语言中time_t数据类型详细介绍
    c语言 static的用法
    C语言中extern的用法
    MATLAB textread函数
    正则表达式
  • 原文地址:https://www.cnblogs.com/bky-hbq/p/13903852.html
Copyright © 2020-2023  润新知