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
      
posted @ 2020-10-30 19:27  nxgy  阅读(69)  评论(0编辑  收藏  举报