程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++中利用構造函數與無名對象簡化運算符重載函數

C++中利用構造函數與無名對象簡化運算符重載函數

編輯:關於C++

在完整描述思想之前,我們先看一下如下的例子,這個例子中的加運算符重載是以非成員函數的方式出現的:

//程序作者:管寧
//站點:www.cndev-lab.com
//所有稿件均有版權,如要轉載,請務必著名出處和作者

#include <iostream>
using namespace std;

class Test
{
public:
Test(int a)
{
Test::a = a;
}
friend Test operator + (Test&,int);
public:
int a;
};

Test operator + (Test &temp1,int temp2)
{
Test result(temp1.a + temp2);
return result;
}
int main()
{
Test a(100);
a = a + 10;//正確
a = 10 + a;//錯誤
cout<<a.a<<endl;
system("pause");
}

上面的代碼是一個自定義類對象與內置整型對象相加的例子,但錯誤行讓我們猛然感覺很詫異,但仔細看看的確也在情理中,參數順序改變後c++無法識別可供使用的運算符重載函數了。

我們為了適應順序問題不得不多加一個幾乎一樣的運算符重載函數。

代碼如下:

//程序作者:管寧
//站點:www.cndev-lab.com
//所有稿件均有版權,如要轉載,請務必著名出處和作者

#include <iostream>
using namespace std;

class Test
{
public:
Test(int a)
{
Test::a = a;
}
friend Test operator + (Test&,int);
friend inline Test operator + (Test&,int);
public:
int a;
};
Test operator + (Test &temp1,int temp2)
{
Test result(temp1.a + temp2);
return result;
}
inline Test operator + (int temp1,Test &temp2)//利用內聯函數的定義提高效率
{
return temp2+temp1;
}
int main()
{
Test a(100);
a = a + 10;//正確
a = 10 + a;//正確
cout<<a.a<<endl;
system("pause");
}

代碼中我們使用內聯函數的目的是為了縮減開銷,但事實上我們仍然覺得是比較麻煩的,例子中的情況都還是非成員函數的情況,如果運算符重載函數是作為類成員函數,那麼問題就來了,重載函數的第一個參數始終被隱藏,我們無發讓int形參排列在隱藏參數的前面,從而導致a = 10 + a;無法獲取正確的運算符重載函數。

有問題的代碼如下:

class Test
{
public:
Test(int a)
{
Test::a = a;
}
Test operator + (int temp2)
{
Test result(temp1.a + temp2);
return result;
}
Test operator + ()//第一個參數被隱藏,怎麼辦????,int形參無法放到this指針的前面,理想中的應該是(int temp1,Test *this)
{
}
public:
int a;
};

對於這個問題難道沒有辦法解決嗎?

答案是否定的,我們可以利用類構造函數對參與運算的整型對象進行顯式的類型轉換,從而生成無名對象參與同類型對象的加運算,這樣做可以縮減代碼量,提高程序的可讀性。

代碼如下(例一為非成員形式,例二為成員形式):

//例一

//程序作者:管寧
//站點:www.cndev-lab.com
//所有稿件均有版權,如要轉載,請務必著名出處和作者

#include <iostream>
using namespace std;

class Test
{
public:
Test(int a)//事實上構造函數起的轉換作用本質就是產生無名對象
{
Test::a = a;
}
friend Test operator + (Test&,Test&);
public:
int a;
};
Test operator + (Test &temp1,Test &temp2)
{
Test result(temp1.a + temp2.a);
return result;
}
int main()
{
Test a(100);
a = a + Test(10);//顯式轉換,產生無名對象
a = Test(10) + a;
cout<<a.a<<endl;
a = 50 + 1;//先進行50+1的內置整型的加運算,然後進行a=Test(51)的隱式轉換
cout<<a.a<<endl;
system("pause");
}

//例二 

//程序作者:管寧
//站點:www.cndev-lab.com
//所有稿件均有版權,如要轉載,請務必著名出處和作者
#include <iostream>
using namespace std;
class Test
{
public:
Test(int a)//事實上構造函數起的轉換作用本質就是產生無名對象
{
Test::a = a;
}
Test operator + (Test &temp)//第一個參數即使隱藏也沒有關系,因為是以Test類型的無名對象參與運算的
{
Test result(this->a + temp.a);
return result;
}
public:
int a;
};
int main()
{
Test a(100);
a = a + Test(10);
a = Test(10) + a;
cout<<a.a<<endl;
a = 50 + 1;//先進行50+1的內置整型的加運算,然後進行a=Test(51)的隱式轉換
cout<<a.a<<endl;
system("pause");
}

認真觀察了上面的兩個例子後我們可以發現,類的構造函數起了顯式或者隱式轉換的作用,轉換過程實質是產生一個類的無名對象,類的運算符重載函數的參數就是這個無名對象的引用,所以參數的順序也不再是問題,代碼的運行效率也得到提高,無需再定義只是參數順序不同,內容重復的運算符重載函數了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved