zoukankan      html  css  js  c++  java
  • 第34课 数组操作符的重载

    string类对象还具备C方式字符串的灵活性吗?还能直接访问单个字符吗?
    string类最大限度的考虑了C字符串的兼容性
    可以按照使用C字符串的方式使用string对象

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
        string s = "a1b2c3d4";
        int n = 0;
    
        for(int i = 0; i<s.length(); i++)
        {
            if(isdigit(s[i]))
            {
                n++;
            }
        }
    
        cout << n << endl;
    
    }

    从上面的例子可以看出,string类对象是支持数组的下标访问的?

    问题:难道类的对象也支持数组的下标访问?

    举个简单的例子:

    #include <iostream>
    
    using namespace std;
    
    class Test
    {
    
    };
    int main()
    {
        Test t;
        cout << t[0] << endl;
    
    }

     说明C++编译器并不认可将数组访问操作符和任意的类对象共同使用。

    被忽略的事实:
    -数组访问操作符是C/C++中的内置操作符(和+ - * /地位是一样的)
    -数组访问符的原生意义是数组访问指针运算

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

    指针与数组的复习

    #include <iostream>
    
    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;
        }
    
        for(int i=0; i<5; i++)
        {
            i[a] = i+10;
        }
    
        for(int i=0; i<5; i++)
        {
            cout << *(i + a) << endl;
        }
    
    
        return 0;
    }

    数组访问操作符([])

    -只能通过类的成员函数重载

    -重载函数能且仅能使用一个参数

    -可以定义不同参数的多个重载函数

    根据上面的规则,编写数组操作符的重载函数

    #include <iostream>
    
    using namespace std;
    
    class Test
    {
    
    public:
         int operator [](int n)
         {
             return 0;
         }
    
         int operator [](const char *s)
         {
             return 0;
         }
    };
    
    int main()
    {
    
        Test t;
        cout << t[1] << endl;
        return 0;
    }

    上面的程序编译正确,在语法上面是ok的。

    #include <iostream>
    
    using namespace std;
    
    class Test
    {
    private:
         int a[5];
    
    public:
         int operator [](int i)
         {
             return a[i];
         }
    
         int operator [](const char *s)
         {
             return 0;
         }
    
         int getLength()
         {
             return 5;
         }
    };
    
    int main()
    {
    
        Test t;
    
        for(int i=0; i<t.getLength(); i++)
        {
            t[i] = i;
        }
    
        for(int i=0; i<t.getLength(); i++)
        {
            cout << t[i] <<endl;
        }
    
        return 0;
    }

     编译时,提示有一个不合法的左值。即t[i] = i不合法。

    将该条语句改为它的等价形式:t.operator[](i)=i; 此时想要将i赋给函数的返回值,这样肯定不合法,函数调用的返回值怎么能够作为左值使用呢?

    要考虑一下,有没有什么技术可以使函数的返回值出现在赋值符号的左边---------引用就登场了。

    int operator [](int i)
     {
        return a[i]; //在这里我们想要返回的是数组元素的返回值,此时可以返回引用。
     }
    #include <iostream>
    
    using namespace std;
    
    class Test
    {
    private:
         int a[5];
    
    public:
         int& operator [](int i)
         {
             return a[i];
         }
    
         int& operator [](const char *s)
         {
             return a[0];
         }
    
         int getLength()
         {
             return 5;
         }
    };
    
    int main()
    {
    
        Test t;
    
        for(int i=0; i<t.getLength(); i++)
        {
            //t.operator [](i) = i;
              t[i] = i;
        }
    
        for(int i=0; i<t.getLength(); i++)
        {
            cout << t[i] <<endl;
        }
    
        return 0;
    }
    
    
    int& operator [](const char *s)
     {
             return a[0];
     }
    这个数组操作符重载函数挺怪异的,它的参数是一个字符指针,究竟它想做什么呢?
    其实它想要实现通过字符串来访问一个数组:
    
    
    #include <iostream>
    
    using namespace std;
    
    class Test
    {
    private:
         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]; //默认返回a[0]
    
         }
    
         int getLength()
         {
             return 5;
         }
    };
    
    int main()
    {
    
        Test t;
    
        for(int i=0; i<t.getLength(); i++)
        {
            //t.operator [](i) = i;
              t[i] = i;
        }
    
        for(int i=0; i<t.getLength(); i++)
        {
            cout << t[i] <<endl;
        }
        //以字符串的形式访问一个数组,以前在C语言中见都没见过。
        cout << t["1st"] << endl;
        cout << t["2nd"] << endl;
        cout << t["3rd"] << endl;
        cout << t["4th"] << endl;
        cout << t["5th"] << endl;
    
        return 0;
    }

    编译通过,说明以字符串为下标访问一个数组是合法的。

    做这个演示的目的:

    如果要学习C++的后续语言,比如C#,D语言等,确实可以将一个字符串作为一个下标来访问一个数组。以后再碰见这种用法,千万不要觉得奇怪。

     
     
     
    #include<iostream>
    
    
    usingnamespacestd;
    
    
    intmain()
    {
    inta[5]={0};
    
    
    for(inti=0;i<5;i++)
    {
    a[i]=i;
    }
    
    
    for(inti=0;i<5;i++)
    {
    cout<<*(a+i)<<endl;
    }
    
    
    for(inti=0;i<5;i++)
    {
    i[a]=i+10;
    }
    
    
    for(inti=0;i<5;i++)
    {
    cout<<*(i+a)<<endl;
    }
    
    
    
    
    return0;
    }
    
    
    
    
    
    
  • 相关阅读:
    LeetCode 43. 字符串相乘(Multiply Strings)
    LeetCode 541. 反转字符串 II(Reverse String II)
    枚举类型
    c#字母加密
    汇率兑换Python
    冒泡排序c#
    c#
    HTML
    日历
    Java2
  • 原文地址:https://www.cnblogs.com/-glb/p/11923860.html
Copyright © 2011-2022 走看看