1. 程式人生 > >C++PrimerPlus學習之使用類

C++PrimerPlus學習之使用類

運算子過載

  • 一個例子

    //mytime0.h
    #ifndef MYTIME0_H_INCLUDED
    #define MYTIME0_H_INCLUDED
    
    class Time
    {
    private:
        int hours;
        int minutes;
    public:
        Time(){hours=minutes=0;}
        Time(int h,int m=0){hours=h+m/60;minutes=m%60;}
        void show()const{std::cout<<hours<<" hours, "<<minutes<<
    " minutes\n";} //operator Time operator+(const Time &t)const//返回型別不要使用引用 { Time sum; sum.minutes=minutes+t.minutes; sum.hours=hours+t.hours; sum.hours=sum.hours+sum.minutes/60; sum.minutes%=60; return sum; } Time operator*(const int &
    v)const//另一種過載方式,非同型別過載 { return Time(hours*v,minutes*v); } }; #endif // MYTIME0_H_INCLUDED //main.cpp #include<bits/stdc++.h> #include"mytime0.h" using namespace std; int main() { Time thetime=Time(12,15); thetime.show(); Time lxttime=Time(11,5); thetime=thetime+lxttime;
    thetime.show(); }
  • 過載限制

    • 過載後的運算子必須至少一個運算元是使用者定義的型別
    • 使用運算子過載不能違反運算子原來的句法規則 – 運算元的個數 和 優先順序
    • 不能建立新運算子
    • 有些運算子不能過載 – 可百度一下
    • 有些運算子只能通過成員函式過載 – 而不能通過非成員函式過載
      • = ,() , [] , ->

友元函式

  • 過載遺留下的問題
    thetime=thetime*2;//allowed
    thetime=2*thetime;//not allowed
    

我們只能使用非成員函式解決改問題,但常規非成員函式不能訪問私有成員,只有一類特殊的非成員函式可以訪問類的私有成員-友元函式。

  • 宣告

    • 原型放在類中,但不是類成員函式,不用使用::
    • 前加friend,定義不用加,可訪問類的私有成員。
      friend Time operator*(double m,const Time &t);
      
  • 定義

    • 不用加friend
    • 不用加 類名::
  • 常見的友元函式

    ostream & operator<<(ostream & os,const c_name &obj)
    {
      os << ...;
      return os;
    }
    
  • 改進後的Time類

    #ifndef MYTIME0_H_INCLUDED
    #define MYTIME0_H_INCLUDED
    #include<iostream>
    class Time
    {
    private:
        int hours;
        int minutes;
    public:
        Time(){hours=minutes=0;}
        Time(int h,int m=0){hours=h+m/60;minutes=m%60;}
        void show()const{std::cout<<hours<<" hours, "<<minutes<<" minutes\n";}
    
        //operator
        Time operator+(const Time &t)const//返回型別不要使用引用
        {
            Time sum;
            sum.minutes=minutes+t.minutes;
            sum.hours=hours+t.hours;
            sum.hours=sum.hours+sum.minutes/60;
            sum.minutes%=60;
            return sum;
        }
        Time operator*(const int &v)const//另一種過載方式,非同型別過載
        {
            return Time(hours*v,minutes*v);
        }
        friend Time operator*(int v,const Time &t)
        {
            return t*v;
        }
        friend std::ostream &operator<<(std::ostream &os,const Time &t)
        {
            os<<t.hours<<" hours, "<<t.minutes<<" minutes\n";
            return os;
        }
    };
    #endif // MYTIME0_H_INCLUDED
    //main.cpp 
    #include<bits/stdc++.h>
    #include"mytime0.h"
    using namespace std;
    int main()
    {
        Time thetime=Time(12,15);
        thetime=2*thetime;//allowed
        cout<<thetime<<endl;
        return 0;
    }
    
    

類的轉換

  • 其他型別轉換成類
    • 只含有一個引數的建構函式可以作為轉換函式,進行自動(隱式轉換)
    • 構造時應避免二義性。
      Time(int h);//建構函式
      Time mytime;
      mytime=16;
      
    • explicit關鍵字
      • 有時候不需要這種自動特性,宣告時使用該關鍵字即可。
        explicit Time(int h)
        Time mytime=16;//not allowed
        mytime=Time(16);//allowed
        mytime=(Time)16;//allowed
        
  • 該類轉換成其他型別
    • 應避免二義性
    • 有時候會出現錯誤,故在宣告轉換函式時加上explicit,並使用顯式轉換。
    • 或者另外宣告一個成員函式來進行型別轉換。
    • 宣告
      explicit operator int() const
      
    • 定義
      Time::explicit operator int()const
      {
        return hours;
      }