C++運算符重載

C++中預約義的運算符的操做對象只能是基本數據類型。但實際上,對於許多用戶自定義類型(例如類),也須要相似的運算操做。這時就必須在C++中從新定義這些運算符,賦予已有運算符新的功能,使它可以用於特定類型執行特定的操做。運算符重載的實質是函數重載,它提供了C++的可擴展性。函數

運算符重載是經過建立運算符函數實現的,運算符函數定義了重載的運算符將要進行的操做。運算符函數的定義與其餘函數的定義相似,唯一的區別是運算符函數的函數名是由關鍵字operator和其後要重載的運算符符號構成的。運算符函數定義的通常格式以下:
<返回類型說明符> operator <運算符符號>(<參數表>)
{
<函數體>
}spa

(1) 除了類屬關係運算符"."、成員指針運算符".*"、做用域運算符"::"、sizeof運算符和三目運算符"?:"之外,C++中的全部運算符均可以重載。指針

(2) 重載運算符限制在C++語言中已有的運算符範圍內的容許重載的運算符之中,不能建立新的運算符。code

(3) 運算符重載實質上是函數重載,所以編譯程序對運算符重載的選擇,遵循函數重載的選擇原則。對象

(4) 用戶自定義類的運算符通常都必須重載後方可以使用,但兩個例外,運算符「=」和「&」沒必要用戶重載.blog

 

哪些運算符能夠用做重載?幾乎全部的運算符均可用做重載。具體包含:
算術運算符:=,-,*,/,%,++,--
位操做運算符:—,|,~,^,<<,>>;
邏輯運算符:!&&,||;
比較運算符:>,<,>=,<=,==,!=
賦值運算符:=,+=,- = ,*=,%=,\=^=,<<=,>>=;
其餘運算符:[ ],()->, ',new,delete,new[],delete[],->* .作用域

 

運算符有兩種重載形式:成員函數形式和友元函數形式。這兩種形式均可訪問類中的私有成員。it

實例:自定義一個int包裹類,包裝int,而且支持+運算符和=運算符io

 

 1.用成員函數來重載運算符編譯

複製代碼
class Integer {
public:
Integer();
Integer(int value);
Integer operator+(int value);
void operator=(int value);
private:
int m_value;
};
複製代碼

 

複製代碼
//integer.cpp
#include "integer.h"

Integer::Integer() {
m_value = 0;
}
Integer::Integer(int value) {
m_value = value;
}

Integer Integer::operator+(int value) {
int tmpValue = m_value + value;
return Integer(tmpValue);
}

void Integer::operator=(int value) {
m_value = value;
}
複製代碼



使用示例:

 

Integer integer = Integer(10); 
Integer tmpInteger = 100; //重載=運算符
tmpInteger = integer + 1; //重載+運算符

 

2.使用友元函數來重載運算符

  使用成員函數重載運算符,咱們作到了實現 integer + 1,但是若是是 1 + integer呢,這個時候咱們必須使用友元函數重載+運算符:

 

複製代碼
//integer.h
class Integer {
public:
Integer();
Integer(int value);
Integer operator+(int value);
void operator=(int value);
operator int() const;
private:
int m_value;

friend Integer operator+(int value, Integer integer);
};

//Integer operator +(Integer integer, int value); //不能聲明該函數,不然會和成員函數衝突
Integer operator+(int value, Integer integer);
複製代碼

 

 

複製代碼
//integer.cpp
#include "integer.h"

Integer::Integer() {
m_value = 0;
}
Integer::Integer(int value) {
m_value = value;
}

Integer Integer::operator+(int value) {
int tmpValue = m_value + value;
return Integer(tmpValue);
}

void Integer::operator=(int value) {
m_value = value;
}
Integer::operator int() const {
return m_value;
}

Integer operator+(int value, Integer integer) {
int tmpValue = integer.m_value + value;
return Integer(tmpValue);
}
複製代碼

使用示例:

 

Integer integer = Integer(10);  
Integer tmpInteger = 100; //重載=運算符
tmpInteger = integer + 1; //重載Integer成員函數+運算符
tmpInteger = 1 + tmpInteger;//重載友元函數+運算符

 

轉換運算符重載:

   從上述代碼咱們看到Integer integer = 1;(隱式調用構造函數),確實很方便,可是若是要實現 int i = Integer(100),實現自定義類型到內部類型的轉換或者已有的類型,就須要轉換運算符了。

   轉換運算符的的形式以下:

   X::operator T()

   其中T是類型。

   代碼示例以下:

   

複製代碼
//integer.h
class Integer {
public:
Integer();
Integer(int value);
Integer operator+(int value);
void operator=(int value);
operator int() const; //int 轉換運算符
private:
int m_value;

friend Integer operator+(int value, Integer integer);
};

//Integer operator +(Integer integer, int value); //不能聲明該函數,不然會和成員函數衝突
Integer operator+(int value, Integer integer);
複製代碼

 

複製代碼
//integer.cpp
#include "integer.h"

#include <stdio.h>
#include <stdlib.h>
Integer::Integer() {
m_value = 0;
}
Integer::Integer(int value) {
m_value = value;
}

Integer Integer::operator+(int value) {
int tmpValue = m_value + value;
return Integer(tmpValue);
}

void Integer::operator=(int value) {
m_value = value;
}
Integer::operator int() const {
return m_value;
}

Integer operator+(int value, Integer integer) {
int tmpValue = integer.m_value + value;
return Integer(tmpValue);
}
複製代碼

使用示例:

 

Integer integer = Integer(10);  
Integer tmpInteger = 100; //重載=運算符
tmpInteger = integer + 1; //重載Integer成員函數+運算符
tmpInteger = 1 + tmpInteger;//重載友元函數+運算符
int num = tmpInteger; //重載int 轉換運算符

 

 重載++運算符:

  前綴各後綴運算兩種,爲了區分這兩種運算,將後綴運算符視爲雙目運算符,示例代碼以下:

 

複製代碼
//integer.h
class Integer {
public:
Integer();
Integer(int value);
Integer operator+(int value);
void operator=(int value);
operator int() const; //int 轉換運算符
Integer operator++(); //重載 ++Integer
Integer operator++(int value);//重載 Integer++
private:
int m_value;

friend Integer operator+(int value, Integer integer);
};

//Integer operator +(Integer integer, int value); //不能聲明該函數,不然會和成員函數衝突
Integer operator+(int value, Integer integer);
複製代碼

 

 

複製代碼
//integer.cpp
#include "integer.h"

Integer::Integer() {
m_value = 0;
}
Integer::Integer(int value) {
m_value = value;
}

Integer Integer::operator+(int value) {
int tmpValue = m_value + value;
return Integer(tmpValue);
}

void Integer::operator=(int value) {
m_value = value;
}
Integer::operator int() const {
return m_value;
}

Integer Integer::operator++() {
Integer tmpInteger;
tmpInteger = ++m_value;
return tmpInteger;
}
Integer Integer::operator++(int value) {
Integer tmpInteger;
tmpInteger = m_value++;
return tmpInteger;
}

Integer operator+(int value, Integer integer) {
int tmpValue = integer.m_value + value;
return Integer(tmpValue);
}
複製代碼

使用示例:

 

複製代碼
    Integer integer = Integer(10);  
Integer tmpInteger = 100; //重載=運算符
tmpInteger = integer + 1; //重載Integer成員函數+運算符
tmpInteger = 1 + tmpInteger;//重載友元函數+運算符
int num = tmpInteger; //重載int 轉換運算符
tmpInteger = integer++; //重載 Integer++
tmpInteger = ++integer; //重載 ++Integer
複製代碼

 

兩種重載形式的比較:在多數狀況下,將運算符重載爲類的成員函數和類的友元函數都是能夠的。但成員函數運算符與友元函數運算符也具備各自的一些特色:(1) 通常狀況下,單目運算符最好重載爲類的成員函數;雙目運算符則最好重載爲類的友元函數。(2) 如下一些雙目運算符不能重載爲類的友元函數:=、()、[]、->。(3) 類型轉換函數只能定義爲一個類的成員函數而不能定義爲類的友元函數。(4) 若一個運算符的操做須要修改對象的狀態,選擇重載爲成員函數較好。(5) 若運算符所需的操做數(尤爲是第一個操做數)但願有隱式類型轉換,則只能選用友元函數。(6) 當運算符函數是一個成員函數時,最左邊的操做數(或者只有最左邊的操做數)必須是運算符類的一個類對象(或者是對該類對象的引用)。若是左邊的操做數必須是一個不一樣類的對象,或者是一個內部類型的對象,該運算符函數必須做爲一個友元函數來實現。(7) 當須要重載運算符具備可交換性時,選擇重載爲友元函數。

相關文章
相關標籤/搜索