第34课 数组操作符的重载

1. 字符串类的兼容性

(1)string类最大限度的考虑了C字符串兼容性

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

string s = "abcedefg";

char c = s[i];

 

【编程实验】用C方式使用string类   34-1.cpp

#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])) //通过C字符串方式使用string对象(即数组)

        {

            n++;

        }

    }

   

    cout << n << endl; //4

 

    return 0;

}

运行结果:

  

 

2. 类的对象如何支持数组的下标访问

(1)数组访问C/C++中的内置操作符

(2)数组访问符原生意义数组访问指针运算

          a[n] ←→  *(a + n)  ←→  *(n + a)  ←→ n[a]

 

【实例分析】指针和数组的复习   34-2.cpp

#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;

}

运行结果:

  

 

3. 重载数组访问的操作符:[]

(1)只能通过类的成员函数重载

(2)重载函数能且仅能使用一个参数

(3)可以定义不同参多个重载函数

(4)可以隐藏对指针的操作

 

【编程实验】重载数组访问操作符   34-4.cpp

#include <iostream>

#include <string>

 

using namespace std;

 

class Test

{

private:

    int a[5];

public:

    //重载数组操作符,能且只能一个参数

    //返回值为引用,可以作为左值使用!即,

    //Test t;

    //t[1] = 2;

    int& operator[](int i)

    {

        return a[i];

    }

   

    int& operator[](const string& s)

    {

        if (s == "lst"){

            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 sizeof(a) / sizeof(*a);}

};

int main() { Test t; for(int i = 0; i < t.length(); i++) { //通过下标方式访问对象,但本质上重载操作符 //是个函数,即t[i]是通过函数调用(而不是数组)来访问的 t[i] = i;//操作符[]返回的是引用,可以作为左值 } for(int i = 0; i < t.length(); i++) { cout << t[i] << endl; } cout << t["5th"] << endl; //4,t["5th"],本质上是个函数调用 cout << t["4th"] << endl; //3 cout << t["3rd"] << endl; //2 cout << t["2nd"] << endl; //1 cout << t["1st"] << endl; //0 return 0; }

运行结果:

  

 

【编程实验】数组类的完善   IntArray

//IntArray.h

#ifndef _INTARRAY_H_

#define _INTARRAY_H_

 

class IntArray

{

private:

    int m_length;

    int* m_pointer;

 

    //将构造函数变为私有的

    IntArray(int len);

    bool construct(); //第2阶构造函数

 

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;

}

 

IntArray::~IntArray()

{

    if(m_pointer)

    {

        delete[] m_pointer;

    }

}

 

int IntArray::length()

{

    return m_length;

}

 

bool IntArray::get(int index, int& value)

{

   bool bRet = (0 <= index) && (index <m_length);

 

   if(bRet)

   {

        value = m_pointer[index];

   }

 

   return bRet;

}

 

bool IntArray::set(int index, int value)

{

 

   bool bRet = (0 <= index) && (index <m_length);

 

   if(bRet)

   {

        m_pointer[index] = value;

   }

 

   return bRet;

}

 

int& IntArray::operator[](int index)

{

    return m_pointer[index];

}

 

IntArray& IntArray::self()

{

    return *this;

}

 

//main.cpp

#include <iostream>

#include "IntArray.h"

 

using namespace std;

 

int main()

{

    IntArray* a = IntArray::NewInstance(5);

 

    if(a != NULL)

    {

        //得到对象的引用,避免使用指针的麻烦。

        //如使用引用方式访问第i个元素:array[i],很直观

        //但使用指针方式访问第i个元素: (*a)[i], 不直观

        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;

}

运行结果:

  

 

4. 小结

(1)string最大程序的兼容了C字符串的用法

(2)数组访问符重载能够使得对象模拟数组的行为

(3)只能通过类的成员函数重载数组访问符

(4)重载函数能且仅能使用一个参数

posted @ 2018-12-23 11:22  梦心之魂  阅读(135)  评论(0编辑  收藏  举报