重載/友元

  重載分爲函數重載和運算符重載!重載本身的概念在C++中通俗含義是:相同的某個元素表達不同的意思!我們首先來看函數重載。

函數重載

  函數重載本身時比較簡單明瞭的,即定義同一個函數名稱,通過設置不同的傳入參數來使之成爲不同的函數!如下所示:

 Time();
 Time(int h, int m = 0);

在類聲明中聲明同一個函數名稱Time(注意,這是個特殊的函數,我們稱之爲構造函數,即創建對象時,將自動調用此成員函數),但是由於第一個函數,默認沒有參數,第二個函數默認傳入參數h,m。所以,我們在使用此函數名稱時,編譯器會根據函數的形式,自動匹配相應的函數是現!如我們創建一個對象:

Time planing;

可以看到,沒有傳遞任何參數,所以編譯器調用默認構造函數,即

Time()

我們如果再創建一個對象:

Time coding(2,40);

顯然,這裏將調用第二個構造函數,即

Time(int h,int m);

  關於編譯器如何匹配重載函數,建議閱讀如下文章:吳秦:C++的函數重載。希望對構造函數能夠有深刻的理解!
  有的人說了,爲什麼要整出個重載呢? 試想想,如果你要實現n個相似的功能的函數,而要定義n個不同名稱的函數是個多麼混亂和複雜的事情。重載函數的存在就是爲了簡化此類函數的定義。
  再來看看運算符重載!
運算符重載
我們舉個例子,假如定義一個類TIME,包含兩個私有變量hour,minutes。如下所示:

class Time
{
private:
    int hours;
    int minutes;
public:
    Time();
    Time(int h, int m = 0);
    void AddMin(int m);
    void AddHr(int h);
    void Reset(int h = 0, int m = 0);
    const Time Sum(const Time & t) const;
    void Show() const;
};

如果現在有兩個對象,我們需要求兩個對象a和b中這兩個變量的和,那麼通常的做法是直接通過對象a.hours+a.hours,a.min+b.min即可以實現,那麼可不可以直接a+b呢?答案顯然是不可以的,那我們有方法讓他們直接想加嗎?有!這就需要運算符重載,即拓展運算符的功能!事實上,我們在C語言也見到過如:

c+=1;

其本身就可以理解成“+”號重載的例子!這裏我們稍微拓展一下比如:”2h15min+1h50min”我們該如何實現?
我們首先把它寫成普通的類函數實現:

const Time Time::Sum(const Time & t) const
{
    Time sum;
    sum.minutes = minutes + t.minutes;
    sum.hours = hours + t.hours + sum.minutes / 60;
    sum.minutes %= 60;
    return sum;
}

然後,通過運算符重載來實現這個函數!所以我們不得不“祭出”運算符重載的關鍵字“opertor”。轉換的函數實現如下:

Time Time::operator+(const Time & t) const
{
    Time sum;
    sum.minutes = minutes + t.minutes;
    sum.hours = hours + t.hours + sum.minutes / 60;
    sum.minutes %= 60;
    return sum;
}

注意到,函數實現本身並沒有發生變換,只不過把原來的sum改爲opertor+,所以,理論上我們依然可以通過普通調用方式:

total=a.operater+(b);

來調用此函數,然而一個更合適的方式是直接省略opertor,而寫成:

total=a+b;

注意:重載運算符左側的對象是調用對象,即默認的對象函數本身,重載運算符右邊的對象是傳入的對象的參數——這是一個編譯器默認的規則,必須遵守!
  根據這個例子,我們當然可以定義opertor-,opertor*等語法允許的重載運算符!(c++在重載運算符的定義中會有相應的限制,如不能定義opertor+爲“減”功能,等等!建議在使用中再注意查詢!)如下:

 Time operator+(const Time & t) const;
 Time operator-(const Time & t) const;
 Time operator*(double n) const;

我們注意到有一個重載運算符是 opertor*,它使得我們可以做出

coding*1.5

這種——即不同數據類型的相運算的方式,如前所述不能寫成

1.5*coding

因爲1.5並不是opertor*所屬類的成員變量!那麼有沒有什麼替代方法呢?有!我們可以定義一個非成員函數來解決類似的問題:

Time opertor*(int multi,Time & t );

但是,我們會面臨另一個問題:即非成員函數是不能訪問成員函數內部的私有變量!於是就引入了一個新的概念:友元函數!
友元函數
友元函數的創建方法如下:

friend Time operator*(double m, const Time & t)
    { return t * m; } 

這樣,我們就可以在該函數中調用私有變量,即當我們寫出:

A=2.75*B

將被解釋爲:

A=operater*(2.75,B)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章