1、函數調用運算符 () 可以被重載用於類的對象。當重載 () 時,您不是創造了一種新的調用函數的方式,相反地,這是創建一個可以傳遞任意數目參數的運算符函數。
下面的實例演示瞭如何重載函數調用運算符 ()。
#include <iostream>
using namespace std;
class Distance
{
private:
int feet; // 0 到無窮
int inches; // 0 到 12
public:
// 所需的構造函數
Distance(){
feet = 0;
inches = 0;
}
Distance(int f, int i){
feet = f;
inches = i;
}
// 重載函數調用運算符
Distance operator()(int a, int b, int c)
{
Distance D;
// 進行隨機計算
D.feet = a + c + 10;
D.inches = b + c + 100 ;
return D;
}
// 顯示距離的方法
void displayDistance()
{
cout << "F: " << feet << " I:" << inches << endl;
}
};
int main()
{
Distance D1(11, 10), D2;
cout << "First Distance : ";
D1.displayDistance();
D2 = D1(10, 10, 10); // invoke operator()
cout << "Second Distance :";
D2.displayDistance();
return 0;
}
當上面的代碼被編譯和執行時,它會產生下列結果:
First Distance : F: 11 I:10
Second Distance :F: 30 I:120
2、
總結:
需要以類成員函數的形式對函數調用操作符“()”進行重載。
只有常成員函數才能處理常對象,故我們依然在類中提供兩個版本的函數調用操作符重載函數。若調用對象爲常對象(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;
}
當我們用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!”的異常。