1. 程式人生 > >過載操作符operator詳解

過載操作符operator詳解

 operator是C++的關鍵字,它和運算子一起使用,表示一個運算子函式,理解時應將operator=整體上視為一個函式名。

   這是C++擴充套件運算子功能的方法,雖然樣子古怪,但也可以理解:一方面要使運算子的使用方法與其原來一致,另一方面擴充套件其功能只能通過函式的方式(c++中,“功能”都是由函式實現的)。

 一、為什麼使用操作符過載?
對於系統的所有操作符,一般情況下,只支援基本資料型別和標準庫中提供的class,對於使用者自己定義的class,如果想支援基本操作,比如比較大小,判斷是否相等,等等,則需要使用者自己來定義關於這個操作符的具體實現。比如,判斷兩個人是否一樣大,我們預設的規則是按照其年齡來比較,所以,在設計person 這個class的時候,我們需要考慮操作符==,而且,根據剛才的分析,比較的依據應該是age。那麼為什麼叫過載呢?這是因為,在編譯器實現的時候,已經為我們提供了這個操作符的基本資料型別實現版本,但是現在他的運算元變成了使用者定義的資料型別class,所以,需要使用者自己來提供該引數版本的實現。

二、如何宣告一個過載的操作符?
A:  操作符過載實現為類成員函式
過載的操作符在類體中被宣告,宣告方式如同普通成員函式一樣,只不過他的名字包含關鍵字operator,以及緊跟其後的一個c++預定義的操作符。
可以用如下的方式來宣告一個預定義的==操作符:
class person{
private:
    int age;
    public:
    person(int a){
       this->age=a;
    }
   inline bool operator == (const person &ps) const;
};
實現方式如下:
inline bool person::operator==(const person &ps) const
{

     if (this->age==ps.age)
        return true;
     return false;
}
呼叫方式如下:
#include
using namespace std;
int main()
{

  person p1(10);
  person p2(20);
  if(p1==p2) cout<<”the age is equal!”< return 0;
}
這裡,因為operator ==是class person的一個成員函式,所以物件p1,p2都可以呼叫該函式,上面的if語句中,相當於p1呼叫函式==,把p2作為該函式的一個引數傳遞給該函式,從而實現了兩個物件的比較。

B:操作符過載實現為非類成員函式(全域性函式)
對於全域性過載操作符,代表左運算元的引數必須被顯式指定。例如:
#include
#include
using namespace std;
class person
{
public:
int age;
public:
};

bool operator==(person const &p1 ,person const & p2)

//滿足要求,做運算元的型別被顯示指定
{
if(p1.age==p2.age)
return true;
return false;
}
int main()
{
person rose;
person jack;
rose.age=18;
jack.age=23;
if(rose==jack)
cout<<"ok"< return 0;
}

C:如何決定把一個操作符過載為類成員函式還是全域性名字空間的成員呢?
①如果一個過載操作符是類成員,那麼只有當與他一起使用的左運算元是該類的物件時,該操作符才會被呼叫。如果該操作符的左運算元必須是其他的型別,則操作符必須被過載為全域性名字空間的成員。
②C++要求賦值=,下標[],呼叫(), 和成員指向-> 操作符必須被定義為類成員操作符。任何把這些操作符定義為名字空間成員的定義都會被標記為編譯時刻錯誤。
③如果有一個運算元是類型別如string類的情形那麼對於對稱操作符比如等於操作符最好定義為全域性名字空間成員。


D:過載操作符具有以下限制:

(1) 只有C++預定義的操作符集中的操作符才可以被過載;

(2)對於內建型別的操作符,它的預定義不能被改變,應不能為內建型別過載操作符,如,不能改變int型的操作符+的含義;

(3) 也不能為內建的資料型別定義其它的操作符;

(4) 只能過載類型別或列舉型別的操作符;

(5) 過載操作符不能改變它們的操作符優先順序;

(6) 過載操作符不能改變運算元的個數;

(7) 除了對( )操作符外,對其他過載操作符提供預設實參都是非法的;

例項1 過載operator():
struct join_if_joinable
  {
    void operator()(thread& t)
    {
      if (t.joinable())
      {
        t.join();
      }
    }
  };
//use
join_if_joinable(thread1);