• 5.7 C++函数调用操作符重载


    参考:http://www.weixueyuan.net/view/6385.html

    总结:

      需要以类成员函数的形式对函数调用操作符“()”进行重载。

      只有常成员函数才能处理常对象,故我们依然在类中提供两个版本的函数调用操作符重载函数。若调用对象为常对象(const),则必须用常函数。  

      这里面的关于在函数中抛出异常,在调用处捕捉异常,值得参考学习。

    与下标操作符重载函数相同,我们同样需要以类成员函数的形式对函数调用操作符“()”进行重载。其声明语法只有一种形式:
        返回类型 operator()( 参数列表 );

    例1:
    #include<iostream>
    #include<string>
    using namespace std;
    
    class Array
    {
    public:
        Array(){len1 = 0; len2 = 0; num = NULL; };
        Array(int m, int n);
        int & operator()(int, int);
        const int & operator()(int, int)const;
        int getlen1()const {return len1;}
        int getlen2()const {return len2;}
    private:
        int len1;
        int len2;
        int * num;
    };
    
    Array::Array(int m, int n)
    {
        int size = m * n;
        try
        {
            num = new int[size];
        }
        catch(bad_alloc)
        {
            cerr<<"allocate storage failure!"<<endl;
            throw;
        }
        len1 = m;
        len2 = n;
    }
    
    int & Array::operator()(int i, int j)
    {
        if(i < 0 || i >= len1)
            throw string("1 out of bounds!");
        if(j < 0 || j >= len2)
            throw string("2 out of bounds!");
        return num[ i*len2 + j ];
    }
    
    const int & Array::operator()(int i, int j)const
    {
        if(i < 0 || i >= len1)
            throw string("1 out of bounds!");
        if(j < 0 || j >= len2)
            throw string("2 out of bounds!");
        return num[ i*len2 + j ];
    }
    
    int main()
    {
        Array A(3,4);
        int i,j;
        for(i = 0; i < A.getlen1(); i++)
            for(j = 0; j < A.getlen2(); j++)
                A(i,j) = i * A.getlen2() + j;
        for(i = 0; i < A.getlen1(); i++)
            for(j = 0; j < A.getlen2(); j++)
                cout<< A(i,j)<<" ";
        cout<<endl;
        try
        {
            cout<< A(5, 3) << endl;
        }
        catch(string s)
        {
            cerr<< s <<endl;
        }
        try
        {
            cout<< A(2, 6) << endl;
        }
        catch(string s)
        {
            cerr<< s <<endl;
        }
        return 0;
    }
    在这个例子中我们定义了一个Array类,这个类描述的是一个二维的数组,在类中我们先定义了一个默认构造函数,之后声明了一个带参数的构造函数“Array(int m, int n);”,所带的这两个参数分别是数组的两个维度的大小。之后声明了一个函数调用操作符重载函数“int & operator()(int, int);”和“const int & operator()(int, int)const;”,同样的,因为只有常成员函数才能处理常对象,故我们依然在类中提供两个版本的函数调用操作符重载函数。我们可以去看一下两个函数的函数定义,在它们的函数体中,我们先是做一个越界检测,当然对于二维数组而言,边界是有两个的,因此有两次边界检测的。如果没有越界则会返回对应的值。有了这两个函数调用操作符重载函数,我们就可以用A(i,j)的形式访问二维数组中的数据了。

    当我们用A(i,j)的形式访问二维数组中的数据时,A(i,j)会调用类中的函数调用操作符重载函数,此时A(i,j)可以理解为:
        A.operator()(i, j)
    例1中程序运行结果如下:
        0 1 2 3 4 5 6 7 8 9 10 11
        1 out of bounds!
        2 out of bounds!

    在例1中的主函数中异常捕获语句,我们先运行的是A(5, 3),故而是第一个边界越界了,因此先抛出“1 out of bounds!”的异常,而后又运行A(2, 6),此时为第二个边界越界,抛出“2 out of bounds!”的异常。
     
  • 相关阅读:
    [BetterExplained]书写是为了更好的思考
    java 连接 mysql 数据库 ..password [yes]问题
    学习密度与专注力
    抠鼻屎的方法
    张飞流水账(摘)
    用 C 语言 连接 mysql (问题已解决)
    编程的首要原则(s)是什么?
    Tomat源码学习(二)(转载)
    [BetterExplained]为什么你应该(从现在开始就)写博客
    事件 代理 练习
  • 原文地址:https://www.cnblogs.com/yongpan/p/7803551.html
Copyright © 2020-2023  润新知